/*
 substandard lisp: an implementation of Standard Lisp.
    Copyright (C) 2011 Nicky Nickell

    substandard lisp is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/var APPLY1, APPLYN, BACKQUOTE, CHANNEL_INPUT, CHANNEL_OUTPUT, CLASS_ANY, CLASS_ATOM, CLASS_CONSTANT, CLASS_EBOOLEAN, CLASS_FTYPE, CLASS_JS, CLASS_NUMBER, EOF, EOFC, ERROR_GO, ERROR_INTERNAL, ERROR_RETURN, ERROR_USER, FTYPE_EXPR, FTYPE_FEXPR, FTYPE_MACRO, FUNCTION, NIL, QUOTE, T, TYPE_BOOLEAN, TYPE_CHANNEL, TYPE_FLOATING, TYPE_FUNCTION, TYPE_ID, TYPE_INTEGER, TYPE_JS_FUNC, TYPE_JS_OBJ, TYPE_PAIR, TYPE_STRING, TYPE_UNDEFINED, TYPE_VECTOR, UNDEFINED, UNQUOTE, UNQUOTEL, array_to_list, builtin_function, builtins, class_strings, environment, ftype_strings, homogenize_args, interpreted_builtins, interpreted_fexpr, interpreted_function, interpreted_macro, interpreter, isFloat, isInt, js_to_lisp, lisp_arg_info, lisp_bool, lisp_channel, lisp_docs, lisp_error, lisp_floating, lisp_function, lisp_id, lisp_integer, lisp_js_func, lisp_js_obj, lisp_object, lisp_pair, lisp_string, lisp_to_js, lisp_vector, list_to_array, mask_to_string, namespace, runScripts, std_alert, std_allocate_string, std_apply, std_arg_info, std_backquote, std_ceiling, std_channelreadline, std_char, std_copystring, std_copystringtofrom, std_copyvector, std_copyvectortofrom, std_errorset, std_explode2, std_floor, std_geq, std_help, std_id_sort, std_intern, std_js_apply, std_js_eval, std_js_get, std_js_method_call, std_js_objqmark, std_js_set, std_leq, std_list2vector, std_make_string, std_make_vector, std_mkstring, std_nstring_downcase, std_nstring_upcase, std_prin1_to_string, std_prin2_to_string, std_random, std_rds, std_string, std_string_concat, std_string_downcase, std_string_emptyqmark, std_string_equal, std_string_fetch, std_string_greaterp, std_string_left_trim, std_string_length, std_string_lessp, std_string_not_equal, std_string_not_greaterp, std_string_not_lessp, std_string_repeat, std_string_right_trim, std_string_split, std_string_store, std_string_to_list, std_string_to_vector, std_string_trim, std_string_upcase, std_string_upper_bound, std_stringeqmark, std_stringgtmark, std_stringgtmarkeqmark, std_stringltmark, std_stringltmarkeqmark, std_stringltmarkgtmark, std_substring, std_unquote, std_unquotel, std_vector, std_vector2list, std_vector_emptyqmark, std_vector_fetch, std_vector_size, std_vector_store, std_vector_upper_bound, std_wrs, type_check, type_strings;
var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
  for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
  function ctor() { this.constructor = child; }
  ctor.prototype = parent.prototype;
  child.prototype = new ctor;
  child.__super__ = parent.prototype;
  return child;
}, __indexOf = Array.prototype.indexOf || function(item) {
  for (var i = 0, l = this.length; i < l; i++) {
    if (this[i] === item) return i;
  }
  return -1;
};
FTYPE_EXPR = 0;
FTYPE_FEXPR = 1;
FTYPE_MACRO = 2;
ERROR_RETURN = 0;
ERROR_GO = 1;
ERROR_INTERNAL = 2;
ERROR_USER = 3;
CHANNEL_INPUT = 0;
CHANNEL_OUTPUT = 1;
TYPE_INTEGER = parseInt('00000001', 2);
TYPE_FLOATING = parseInt('00000010', 2);
TYPE_ID = parseInt('00000100', 2);
TYPE_STRING = parseInt('00001000', 2);
TYPE_PAIR = parseInt('00010000', 2);
TYPE_VECTOR = parseInt('00100000', 2);
TYPE_FUNCTION = parseInt('01000000', 2);
TYPE_BOOLEAN = parseInt('10000000', 2);
TYPE_UNDEFINED = parseInt('100000000', 2);
TYPE_CHANNEL = parseInt('1000000000', 2);
TYPE_JS_OBJ = parseInt('10000000000', 2);
TYPE_JS_FUNC = parseInt('100000000000', 2);
CLASS_FTYPE = TYPE_ID;
CLASS_NUMBER = TYPE_INTEGER | TYPE_FLOATING;
CLASS_CONSTANT = CLASS_NUMBER | TYPE_STRING | TYPE_VECTOR | TYPE_FUNCTION;
CLASS_ANY = CLASS_CONSTANT | TYPE_ID | TYPE_PAIR | TYPE_BOOLEAN | TYPE_UNDEFINED | TYPE_CHANNEL | TYPE_JS_OBJ | TYPE_JS_FUNC;
CLASS_EBOOLEAN = CLASS_ANY;
CLASS_ATOM = CLASS_ANY ^ TYPE_PAIR;
CLASS_JS = TYPE_JS_OBJ | TYPE_JS_FUNC;
ftype_strings = {};
ftype_strings[FTYPE_EXPR] = 'expr';
ftype_strings[FTYPE_FEXPR] = 'fexpr';
ftype_strings[FTYPE_MACRO] = 'macro';
type_strings = {};
type_strings[TYPE_INTEGER] = 'integer';
type_strings[TYPE_FLOATING] = 'floating';
type_strings[TYPE_ID] = 'id';
type_strings[TYPE_STRING] = 'string';
type_strings[TYPE_PAIR] = 'pair';
type_strings[TYPE_VECTOR] = 'vector';
type_strings[TYPE_FUNCTION] = 'function';
type_strings[TYPE_BOOLEAN] = 'boolean';
type_strings[TYPE_UNDEFINED] = 'undefined';
type_strings[TYPE_CHANNEL] = 'channel';
type_strings[TYPE_JS_OBJ] = 'js-obj';
type_strings[TYPE_JS_FUNC] = 'js-func';
class_strings = {};
class_strings[CLASS_NUMBER] = 'number';
class_strings[CLASS_CONSTANT] = 'constant';
class_strings[CLASS_ANY] = 'any';
class_strings[CLASS_ATOM] = 'atom';
builtins = {};
interpreted_builtins = {};
lisp_docs = {};
lisp_arg_info = {};
lisp_object = (function() {
  function lisp_object(type, value) {
    this.type = type;
    this.value = value;
  }
  lisp_object.prototype.evaluate = function(env) {
    return this;
  };
  lisp_object.prototype.prin1 = function() {
    return String(this.value);
  };
  lisp_object.prototype.prin2 = function() {
    return String(this.value);
  };
  return lisp_object;
})();
lisp_integer = (function() {
  __extends(lisp_integer, lisp_object);
  function lisp_integer(value) {
    lisp_integer.__super__.constructor.call(this, TYPE_INTEGER, BigInteger(value));
    this.prin2 = this.prin1;
  }
  lisp_integer.prototype.prin1 = function() {
    return this.value.toString();
  };
  return lisp_integer;
})();
lisp_floating = (function() {
  __extends(lisp_floating, lisp_object);
  function lisp_floating(value) {
    lisp_floating.__super__.constructor.call(this, TYPE_FLOATING, Number(value));
    this.prin2 = this.prin1;
  }
  lisp_floating.prototype.prin1 = function() {
    return String(this.value);
  };
  return lisp_floating;
})();
lisp_id = (function() {
  __extends(lisp_id, lisp_object);
  function lisp_id(name, oblist) {
    name = name.replace('!', '');
    if (oblist !== void 0 && oblist[name] !== void 0) {
      return oblist[name];
    }
    lisp_id.__super__.constructor.call(this, TYPE_ID, name);
    this.proplist = {};
    this.flags = {};
    if (oblist !== void 0) {
      oblist[name] = this;
    }
    this.prin2 = this.prin1;
  }
  lisp_id.prototype.evaluate = function(env) {
    return env.variables.get(this.value);
  };
  lisp_id.prototype.prin1 = function() {
    return this.value;
  };
  return lisp_id;
})();
lisp_string = (function() {
  __extends(lisp_string, lisp_object);
  function lisp_string(str) {
    if (/^".*"$/.test(str)) {
      str = eval(str);
    }
    lisp_string.__super__.constructor.call(this, TYPE_STRING, str);
  }
  lisp_string.prototype.prin1 = function() {
    return "\"" + this.value + "\"";
  };
  lisp_string.prototype.prin2 = function() {
    return this.value;
  };
  return lisp_string;
})();
lisp_vector = (function() {
  __extends(lisp_vector, lisp_object);
  function lisp_vector(vect) {
    lisp_vector.__super__.constructor.call(this, TYPE_VECTOR, vect);
  }
  lisp_vector.prototype.prin1 = function() {
    var e, ret, _i, _len, _ref;
    ret = [];
    _ref = this.value;
    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
      e = _ref[_i];
      ret.push(e.prin1());
    }
    return "[" + (ret.join(' ')) + "]";
  };
  lisp_vector.prototype.prin2 = function() {
    var e, ret, _i, _len, _ref;
    ret = [];
    _ref = this.value;
    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
      e = _ref[_i];
      ret.push(e.prin2());
    }
    return "[" + (ret.join(' ')) + "]";
  };
  return lisp_vector;
})();
lisp_pair = (function() {
  __extends(lisp_pair, lisp_object);
  function lisp_pair(car, cdr) {
    this.car = car;
    this.cdr = cdr;
    lisp_pair.__super__.constructor.call(this, TYPE_PAIR);
  }
  lisp_pair.prototype.evaluate = function(env) {
    var func, i, return_value, _ref, _ref2, _ref3, _ref4;
    switch (this.car.type) {
      case TYPE_PAIR:
        func = this.car.evaluate(env);
        break;
      case TYPE_FUNCTION:
        func = this.car;
        break;
      default:
        func = env.functions.get(this.car.value);
        if (func === UNDEFINED) {
          func = env.variables.get(this.car.value);
        }
        if (func === UNDEFINED) {
          throw new lisp_error(ERROR_INTERNAL, T, "undefined function " + this.car.value);
        }
    }
    if (func.type !== TYPE_FUNCTION) {
      throw new lisp_error(ERROR_INTERNAL, T, 'not a function');
    }
    arguments = list_to_array(this.cdr);
    if (!func.arity_check(arguments.length)) {
      throw new lisp_error(ERROR_INTERNAL, T, "improper number of arguments for " + (func.prin1()));
    }
    if (func.ftype === FTYPE_EXPR) {
      for (i = 0, _ref = arguments.length; 0 <= _ref ? i < _ref : i > _ref; 0 <= _ref ? i++ : i--) {
        arguments[i] = arguments[i].evaluate(env);
      }
    }
    if (!func.interpreted) {
      for (i = 0, _ref2 = func.constant_args; 0 <= _ref2 ? i < _ref2 : i > _ref2; 0 <= _ref2 ? i++ : i--) {
        if (!type_check(arguments[i].type, func.argument_masks[i])) {
          throw new lisp_error(ERROR_INTERNAL, T, "" + (arguments[i].prin1()) + " NOT " + (mask_to_string(func.argument_masks[i])) + " FOR " + (func.prin1()));
        }
      }
      if (func.rest_arg) {
        for (i = _ref3 = func.constant_args, _ref4 = arguments.length; _ref3 <= _ref4 ? i < _ref4 : i > _ref4; _ref3 <= _ref4 ? i++ : i--) {
          if (!type_check(arguments[i].type, func.argument_masks[func.constant_args])) {
            throw new lisp_error(ERROR_INTERNAL, T, "" + (arguments[i].prin1()) + " NOT " + (mask_to_string(func.argument_masks[func.argument_masks.length - 1])) + " FOR " + (func.prin1()));
          }
        }
      }
    }
    if (func.ftype === FTYPE_MACRO) {
      arguments.unshift(this.car);
    }
    arguments = func.parse_args(arguments);
    return_value = func.value(arguments, env);
    if (func.ftype === FTYPE_MACRO) {
      return_value = return_value.evaluate(env);
    }
    return return_value;
  };
  lisp_pair.prototype.prin1 = function() {
    var p, tmp;
    tmp = [];
    p = this;
    while (true) {
      tmp.push(p.car.prin1());
      if (p.cdr === NIL) {
        break;
      } else if (!(p.cdr.type & TYPE_PAIR)) {
        tmp.push('.');
        tmp.push(p.cdr.prin1());
        break;
      }
      p = p.cdr;
    }
    return "(" + (tmp.join(' ')) + ")";
  };
  lisp_pair.prototype.prin2 = function() {
    var p, tmp;
    tmp = [];
    p = this;
    while (true) {
      tmp.push(p.car.prin2());
      if (p.cdr === NIL) {
        break;
      } else if (!(p.cdr.type & TYPE_PAIR)) {
        tmp.push('.');
        tmp.push(p.cdr.prin2());
        break;
      }
      p = p.cdr;
    }
    return "(" + (tmp.join(' ')) + ")";
  };
  return lisp_pair;
})();
lisp_bool = (function() {
  __extends(lisp_bool, lisp_object);
  function lisp_bool(value) {
    lisp_bool.__super__.constructor.call(this, TYPE_BOOLEAN, value);
    this.car = this;
    this.cdr = this;
    this.prin2 = this.prin1;
  }
  lisp_bool.prototype.prin1 = function() {
    if (this.value === true) {
      return 'T';
    } else {
      return 'NIL';
    }
  };
  return lisp_bool;
})();
T = new lisp_bool(true);
NIL = new lisp_bool(false);
UNDEFINED = new lisp_object(TYPE_UNDEFINED, void 0);
EOFC = unescape('%04');
EOF = new lisp_string(EOFC);
lisp_function = (function() {
  __extends(lisp_function, lisp_object);
  function lisp_function(method, constant_args, optional_args, rest_arg, argument_masks, ftype) {
    this.constant_args = constant_args;
    this.optional_args = optional_args;
    this.rest_arg = rest_arg;
    this.argument_masks = argument_masks;
    this.ftype = ftype;
    lisp_function.__super__.constructor.call(this, TYPE_FUNCTION, method);
    this.interpreted = false;
  }
  lisp_function.prototype.parse_args = function() {};
  lisp_function.prototype.arity_check = function(arglen) {
    if (this.rest_arg) {
      return this.constant_args <= arglen;
    } else {
      return this.constant_args <= arglen && arglen <= (this.constant_args + this.optional_args);
    }
  };
  return lisp_function;
})();
builtin_function = (function() {
  __extends(builtin_function, lisp_function);
  function builtin_function(method, arity, rest, argument_masks, ftype) {
    builtin_function.__super__.constructor.call(this, method, arity, 0, rest, argument_masks, ftype);
    this.prin2 = this.prin1;
  }
  builtin_function.prototype.prin1 = function() {
    return "#<BUILTIN:" + this.value.name + ">";
  };
  builtin_function.prototype.parse_args = function(a) {
    var i, rest, ret, _ref, _ref2, _ref3;
    ret = [];
    for (i = 0, _ref = this.constant_args; 0 <= _ref ? i < _ref : i > _ref; 0 <= _ref ? i++ : i--) {
      ret.push(a[i]);
    }
    if (this.rest_arg) {
      rest = [];
      for (i = _ref2 = this.constant_args, _ref3 = a.length; _ref2 <= _ref3 ? i < _ref3 : i > _ref3; _ref2 <= _ref3 ? i++ : i--) {
        rest.push(a[i]);
      }
      ret.push(rest);
    }
    return ret;
  };
  return builtin_function;
})();
interpreted_function = (function() {
  __extends(interpreted_function, lisp_function);
  function interpreted_function(expression, arguments, ftype, env) {
    var args, constant_args, method, optional_args, p, rest_arg;
    this.expression = expression;
    this.arguments = arguments;
    this.env = env != null ? env : null;
    constant_args = 0;
    optional_args = 0;
    rest_arg = false;
    args = [];
    p = arguments;
    while (p !== NIL) {
      if (p.car.value === '&optional' || p.car.value === '&rest') {
        break;
      } else {
        args.push(p.car.value);
        constant_args++;
      }
      p = p.cdr;
    }
    if (p.car.value === '&optional') {
      p = p.cdr;
      while (p !== NIL) {
        if (p.car.value === '&rest') {
          break;
        } else {
          args.push(p.car.value);
          optional_args++;
        }
        p = p.cdr;
      }
    }
    if (p.car.value === '&rest') {
      p = p.cdr;
      args.push(p.car.value);
      rest_arg = true;
    }
    method = function(a, env) {
      var i, ienv, _ref;
      ienv = (this.env !== null ? this.env : env).child_scope();
      for (i = 0, _ref = a.length; 0 <= _ref ? i < _ref : i > _ref; 0 <= _ref ? i++ : i--) {
        ienv.variables._set(args[i], a[i]);
      }
      return this.expression.evaluate(ienv);
    };
    interpreted_function.__super__.constructor.call(this, method, constant_args, optional_args, rest_arg, [], ftype);
    this.interpreted = true;
    this.prin2 = this.prin1;
  }
  interpreted_function.prototype.prin1 = function() {
    return "#<LAMBDA: " + (this.arguments.prin1()) + " " + (this.expression.prin1()) + ">";
  };
  interpreted_function.prototype.parse_args = function(a) {
    var i, rest, ret, total, _ref;
    ret = [];
    total = this.constant_args + this.optional_args;
    for (i = 0; 0 <= total ? i < total : i > total; 0 <= total ? i++ : i--) {
      if (a[i] !== void 0) {
        ret.push(a[i]);
      } else {
        ret.push(NIL);
      }
    }
    if (this.rest_arg) {
      if (a.length > total) {
        rest = [];
        for (i = total, _ref = a.length; total <= _ref ? i < _ref : i > _ref; total <= _ref ? i++ : i--) {
          rest.push(a[i]);
        }
        ret.push(array_to_list(rest));
      } else {
        ret.push(NIL);
      }
    }
    return ret;
  };
  return interpreted_function;
})();
interpreted_fexpr = (function() {
  __extends(interpreted_fexpr, interpreted_function);
  function interpreted_fexpr(expression, arguments) {
    interpreted_fexpr.__super__.constructor.call(this, expression, arguments, FTYPE_FEXPR);
    this.constant_args = 0;
    this.optional_args = 0;
    this.rest_arg = true;
  }
  return interpreted_fexpr;
})();
interpreted_macro = (function() {
  __extends(interpreted_macro, interpreted_function);
  function interpreted_macro(expression, arguments) {
    interpreted_macro.__super__.constructor.call(this, expression, arguments, FTYPE_MACRO);
    this.constant_args = 0;
    this.optional_args = 0;
    this.rest_arg = true;
  }
  return interpreted_macro;
})();
lisp_channel = (function() {
  __extends(lisp_channel, lisp_object);
  function lisp_channel(data, mode, name) {
    if (data == null) {
      data = '';
    }
    this.mode = mode != null ? mode : CHANNEL_INPUT | CHANNEL_OUTPUT;
    this.name = name;
    this.buffer = data;
    this.token_back_buffer = '';
    lisp_channel.__super__.constructor.call(this, TYPE_CHANNEL);
    this.prin2 = this.prin1;
  }
  lisp_channel.prototype.prin1 = function() {
    return "#STREAM(" + this.name + ")";
  };
  lisp_channel.prototype.readtoken = function() {
    var m, ret, _results;
    if (this.token_back_buffer !== '') {
      ret = this.token_back_buffer;
      this.token_back_buffer = '';
      return ret;
    }
    this.gobble_space();
    _results = [];
    while (true) {
      m = this.buffer.match(/^("(?:[^\\"]|\\.)*"|%.*|\[|\]|[('`)]|#'|,@|,|(!.|[^\s\]\[('#,"%)]){1,})|((.|\n)*)$/g);
      this.buffer = m[1] === void 0 ? '' : m[1];
      if (m[0].charAt(0) === '%') {
        this.gobble_space();
        continue;
      }
      if (m[0] === '') {
        return EOFC;
      } else {
        return m[0];
      }
    }
    return _results;
  };
  lisp_channel.prototype.unreadtoken = function(tok) {
    return this.token_back_buffer = tok;
  };
  lisp_channel.prototype.gobble_space = function() {
    return this.buffer = this.buffer.replace(/^\s*|\n/, '');
  };
  lisp_channel.prototype.read = function(env, eof_allowed) {
    var head, next, ptr, t, vect;
    if (eof_allowed == null) {
      eof_allowed = true;
    }
    t = this.readtoken();
    if (t === EOFC) {
      if (eof_allowed === true) {
        return EOF;
      } else {
        throw new lisp_error(ERROR_INTERNAL, T, 'unexpected EOF');
      }
    }
    switch (t) {
      case '(':
        next = this.readtoken();
        if (next === ')') {
          return NIL;
        }
        this.unreadtoken(next);
        head = new lisp_pair(this.read(env), NIL);
        ptr = head;
        next = this.readtoken();
        while (next !== ')') {
          if (next === '.') {
            ptr.cdr = this.read(env);
            this.readtoken();
            break;
          }
          this.unreadtoken(next);
          ptr.cdr = new lisp_pair(this.read(env, false), NIL);
          ptr = ptr.cdr;
          next = this.readtoken();
        }
        return head;
      case ')':
        throw new lisp_error(ERROR_INTERNAL, T, "unexpected token ')'");
        break;
      case '[':
        vect = [];
        while (true) {
          next = this.readtoken();
          if (next === ']') {
            break;
          }
          this.unreadtoken(next);
          vect.push(this.read(env, false));
        }
        return new lisp_vector(vect);
      case ']':
        throw new lisp_error(ERROR_INTERNAL, T, "unexpected token ']'");
        break;
      case '\'':
        return QUOTE(this.read(env), env);
      case '#\'':
        return FUNCTION(this.read(env), env);
      case '`':
        return BACKQUOTE(this.read(env), env);
      case ',':
        return UNQUOTE(this.read(env), env);
      case ',@':
        return UNQUOTEL(this.read(env), env);
      default:
        if (t.toLowerCase() === 't') {
          return T;
        } else if (t.toLowerCase() === 'nil') {
          return NIL;
        } else if (isNaN(t)) {
          if (/".*"/.test(t)) {
            return new lisp_string(t);
          } else {
            return new lisp_id(t, env.oblist);
          }
        } else {
          if (/\d*\.\d*/.test(t)) {
            return new lisp_floating(t);
          } else {
            return new lisp_integer(t);
          }
        }
    }
  };
  lisp_channel.prototype.readline = function() {
    var c, ret;
    ret = '';
    while (true) {
      c = this.readch();
      if (c === EOFC || c === '\n') {
        break;
      } else {
        ret += c;
      }
    }
    return ret;
  };
  lisp_channel.prototype.readch = function() {
    var chr;
    if (this.buffer === '') {
      return EOFC;
    }
    chr = this.buffer.charAt(0);
    this.buffer = this.buffer.substr(1);
    return chr;
  };
  lisp_channel.prototype.write = function(data) {
    return this.buffer += data;
  };
  lisp_channel.prototype.flush = function() {
    var buf;
    buf = this.buffer;
    this.buffer = '';
    return buf;
  };
  return lisp_channel;
})();
lisp_js_obj = (function() {
  __extends(lisp_js_obj, lisp_object);
  function lisp_js_obj(obj) {
    lisp_js_obj.__super__.constructor.call(this, TYPE_JS_OBJ, obj);
    this.prin2 = this.prin1;
  }
  lisp_js_obj.prototype.prin1 = function() {
    return "#JS-OBJ(" + this.value.constructor.name + ")";
  };
  return lisp_js_obj;
})();
lisp_js_func = (function() {
  __extends(lisp_js_func, lisp_object);
  function lisp_js_func(func, scope) {
    this.scope = scope != null ? scope : null;
    lisp_js_func.__super__.constructor.call(this, TYPE_JS_FUNC, func);
    this.prin2 = this.prin1;
    if (this.scope === null) {
      if (typeof window !== 'undefined') {
        this.scope = window;
      } else if (typeof global !== 'undefined') {
        this.scope = global;
      }
    }
  }
  lisp_js_func.prototype.prin1 = function() {
    return "#JS-FUNC(" + this.value.name + ")";
  };
  return lisp_js_func;
})();
lisp_error = (function() {
  function lisp_error(type, value, mess) {
    this.type = type;
    this.value = value;
    if (mess == null) {
      mess = "";
    }
    if (mess.type !== TYPE_STRING) {
      this.mess = new lisp_string(mess);
    } else {
      this.mess = mess;
    }
  }
  return lisp_error;
})();
APPLY1 = function(fn, x) {
  return new lisp_pair(fn, new lisp_pair(x, NIL));
};
APPLYN = function(fn, x) {
  return new lisp_pair(fn, x);
};
QUOTE = function(x, env) {
  return APPLY1(new lisp_id('quote', env.oblist), x);
};
FUNCTION = function(x, env) {
  return APPLY1(new lisp_id('function', env.oblist), x);
};
BACKQUOTE = function(x, env) {
  return APPLY1(new lisp_id('backquote', env.oblist), x);
};
UNQUOTE = function(x, env) {
  return APPLY1(new lisp_id('unquote', env.oblist), x);
};
UNQUOTEL = function(x, env) {
  return APPLY1(new lisp_id('unquotel', env.oblist), x);
};
type_check = function(type, mask) {
  return Boolean(type & mask);
};
isInt = function(x) {
  return x === parseInt(x);
};
isFloat = function(x) {
  return (typeof x === 'number') && !isInt(x);
};
homogenize_args = function(a) {
  var floating, i, integer, ret, _ref, _ref2;
  floating = false;
  integer = false;
  for (i = 0, _ref = a.length; 0 <= _ref ? i < _ref : i > _ref; 0 <= _ref ? i++ : i--) {
    if (a[i].type === TYPE_FLOATING) {
      floating = true;
    } else {
      integer = true;
    }
  }
  if (floating && integer) {
    ret = [];
    for (i = 0, _ref2 = a.length; 0 <= _ref2 ? i < _ref2 : i > _ref2; 0 <= _ref2 ? i++ : i--) {
      if (a[i].type === TYPE_INTEGER) {
        ret.push(new lisp_floating(a[i].value.toJSValue()));
      } else {
        ret.push(a[i]);
      }
    }
    return ret;
  } else {
    return a;
  }
};
mask_to_string = function(mask) {
  var s, set;
  if (class_strings[mask] !== void 0) {
    return class_strings[mask];
  } else {
    set = [];
    for (s in type_strings) {
      if (s & mask) {
        set.push(type_strings[s]);
      }
    }
    if (set.length > 1) {
      return '{' + set.join(', ') + '}';
    } else {
      return set[0];
    }
  }
};
array_to_list = function(arr) {
  var head, i, ptr, _ref;
  head = new lisp_pair(arr.shift(), NIL);
  ptr = head;
  for (i = 0, _ref = arr.length; 0 <= _ref ? i < _ref : i > _ref; 0 <= _ref ? i++ : i--) {
    if (arr[i] === '.') {
      ptr.cdr = arr[++i];
      break;
    }
    ptr.cdr = new lisp_pair(arr[i], NIL);
    ptr = ptr.cdr;
  }
  return head;
};
list_to_array = function(lis) {
  var p, ret;
  ret = [];
  p = lis;
  while (p !== NIL) {
    ret.push(p.car);
    p = p.cdr;
  }
  return ret;
};
lisp_to_js = function(obj) {
  var e, _i, _j, _len, _len2, _ref, _ref2, _results, _results2;
  switch (obj.type) {
    case TYPE_PAIR:
      _ref = list_to_array(obj);
      _results = [];
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        e = _ref[_i];
        _results.push(lisp_to_js(e));
      }
      return _results;
    case TYPE_VECTOR:
      _ref2 = obj.value;
      _results2 = [];
      for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
        e = _ref2[_j];
        _results2.push(lisp_to_js(e));
      }
      return _results2;
    default:
      return obj.value;
  }
};
js_to_lisp = function(obj) {
  var e;
  switch (typeof obj) {
    case 'boolean':
      return new lisp_bool(obj);
    case 'string':
      return new lisp_string(obj);
    case 'number':
      if (isInt(obj)) {
        return new lisp_integer(obj);
      } else {
        return new lisp_floating(obj);
      }
      break;
    case 'object':
      if (obj.constructor !== void 0) {
        if (obj.constructor.name === 'Array') {
          return new lisp_vector((function() {
            var _i, _len, _results;
            _results = [];
            for (_i = 0, _len = obj.length; _i < _len; _i++) {
              e = obj[_i];
              _results.push(js_to_lisp(e));
            }
            return _results;
          })());
        } else {
          return new lisp_js_obj(obj);
        }
      } else {
        return NIL;
      }
      break;
    case 'function':
      return new lisp_js_func(obj);
    default:
      return NIL;
  }
};
namespace = (function() {
  function namespace(up) {
    this.outer = up;
    this.dict = {};
    this.constants = [];
  }
  namespace.prototype.get = function(key) {
    if (this.dict[key] !== void 0) {
      return this.dict[key];
    } else {
      if (this.outer !== void 0) {
        return this.outer.get(key);
      } else {
        return UNDEFINED;
      }
    }
  };
  namespace.prototype.set = function(key, value, constant) {
    if (constant == null) {
      constant = false;
    }
    if (this.dict[key] !== void 0) {
      return this._set(key, value, constant);
    } else {
      if (this.outer !== void 0) {
        return this.outer.set(key, value, constant);
      } else {
        return this._set(key, value, constant);
      }
    }
  };
  namespace.prototype._set = function(key, value, constant) {
    if (constant == null) {
      constant = false;
    }
    if (__indexOf.call(this.constants, key) >= 0) {
      throw new lisp_error(ERROR_INTERNAL, T, 'cannot change the value of constant: ' + key);
    }
    if (constant === true) {
      this.constants.push(key);
    }
    return this.dict[key] = value;
  };
  namespace.prototype.inner_block = function() {
    return new namespace(this);
  };
  return namespace;
})();
environment = (function() {
  function environment(oblist, files, variables, functions) {
    this.oblist = oblist != null ? oblist : {};
    this.files = files != null ? files : {};
    this.variables = variables != null ? variables : new namespace();
    this.functions = functions != null ? functions : new namespace();
  }
  environment.prototype.child_scope = function() {
    return new environment(this.oblist, this.files, this.variables.inner_block(), this.functions);
  };
  return environment;
})();
interpreter = (function() {
  function interpreter(stdin, stdout, stderr) {
    this.stdin = stdin != null ? stdin : new lisp_channel();
    this.stdout = stdout != null ? stdout : new lisp_channel();
    this.stderr = stderr != null ? stderr : new lisp_channel();
  }
  interpreter.prototype.evaluate = function(expr) {
    var errout;
    this.stdin.flush();
    this.stdin.write(expr);
    try {
      return this.toploop.evaluate(this.environment);
    } catch (e) {
      errout = this.environment.variables.get('ERROUT*');
      switch (e.type) {
        case ERROR_GO:
          errout.write('***** GO out of context');
          return this.environment.variables.set('EMSG*', new lisp_string('***** GO out of context'));
        case ERROR_RETURN:
          errout.write('***** RETURN out of context');
          return this.environment.variables.set('EMSG*', new lisp_string('***** RETURN out of context'));
        default:
          errout.write(e.message);
          return this.environment.variables.set('EMSG*', new lisp_string(e.message));
      }
    }
  };
  interpreter.prototype.evaluate_string = function(expr) {
    return ((new lisp_channel(expr).read(this.environment)).evaluate(this.environment)).prin1();
  };
  interpreter.prototype.initialize = function() {
    var func, toploop, _results;
    this.environment = new environment();
    toploop = '(errorset\n\'(let ((expr nil)\n       (result nil))\n  (while t\n    (setq expr (read))\n    (when (eq expr $EOF$)\n      (if (eq IN* STDIN*)\n        (exit)\n        (rds nil)\n        (next)))\n    (setq result (eval expr))\n    (when *OUTPUT\n      (terpri)\n      (prin2 "Value: ")\n      (prin1 result))))\nT NIL)';
    this.toploop = new lisp_channel(toploop).read(this.environment);
    this.environment.variables.set('STDIN*', this.stdin, true);
    this.environment.variables.set('STDOUT*', this.stdout, true);
    this.environment.variables.set('STDERR*', this.stderr, true);
    this.environment.variables.set('IN*', this.stdin);
    this.environment.variables.set('OUT*', this.stdout);
    this.environment.variables.set('ERROUT*', this.stderr);
    this.environment.variables.set('NIL', NIL, true);
    this.environment.variables.set('T', T, true);
    this.environment.variables.set('$EOF$', EOF, true);
    this.environment.variables.set('EMSG*', NIL);
    this.environment.variables.set('*RAISE', NIL);
    this.environment.variables.set('*GSNUM', new lisp_integer(1));
    this.environment.variables.set('*OUTPUT', T);
    for (func in builtins) {
      this.environment.functions.set(func, builtins[func], true);
    }
    _results = [];
    for (func in interpreted_builtins) {
      this.evaluate_string(interpreted_builtins[func]);
      _results.push(this.environment.functions.get(func).constant = true);
    }
    return _results;
  };
  return interpreter;
})();
if (typeof document !== 'undefined') {
  runScripts = function() {
    var s, scripts, _i, _len, _results;
    scripts = (function() {
      var _i, _len, _ref, _results;
      _ref = document.getElementsByTagName('script');
      _results = [];
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        s = _ref[_i];
        if (s.type === 'text/substandard-lisp') {
          _results.push(s);
        }
      }
      return _results;
    })();
    if (scripts.length !== 0) {
      window.lisp = new interpreter();
      lisp.initialize();
    }
    _results = [];
    for (_i = 0, _len = scripts.length; _i < _len; _i++) {
      s = scripts[_i];
      _results.push(lisp.evaluate(s.innerHTML));
    }
    return _results;
  };
  if (window.addEventListener) {
    addEventListener('DOMContentLoaded', runScripts, false);
  } else {
    attachEvent('onload', runScripts);
  }
}
lisp_docs['putd'] = 'explaining what putd is / how it is used!';
lisp_arg_info['putd'] = '[id], [ftype], [function]';
function std_putd(a, env) {
  var fname = a[0];
  var type = a[1];
  var body = a[2];

  switch (type.value) {
  case 'expr':
    body.ftype = FTYPE_EXPR;
    break;
  case 'fexpr':
    body.ftype = FTYPE_FEXPR;
    break;
  case 'macro':
    body.macro = FTYPE_MACRO;
    break;
  default:
    // error?
  }

  env.functions.set(fname.prin1(), body);

  return fname;
};
builtins['putd'] = new builtin_function(std_putd, 3, false, [TYPE_ID, CLASS_FTYPE, TYPE_FUNCTION], FTYPE_EXPR);
lisp_docs['dm'] = 'explaining what dm is / how it is used!';
lisp_arg_info['dm'] = '[id], [pair | boolean], [any]';
function std_dm(a, env) {
  var mname = a[0];
  var param = a[1];
  var fn = a[2];

  if (param == T) {
    // throw some error
  }

  var func = new interpreted_macro(fn, param);

  env.functions.set(mname.prin1(), func);

  return mname;
};
builtins['dm'] = new builtin_function(std_dm, 3, false, [TYPE_ID, TYPE_PAIR | TYPE_BOOLEAN, CLASS_ANY], FTYPE_FEXPR);
lisp_docs['df'] = 'explaining what df is / how it is used!';
lisp_arg_info['df'] = '[id], [pair | boolean], [any]';
function std_df(a, env) {
  var fname = a[0];
  var param = a[1];
  var fn = a[2];

  if (param == T) {
    // throw some error
  }

  var func = new interpreted_fexpr(fn, param);

  env.functions.set(fname.prin1(), func);

  return fname;
};
builtins['df'] = new builtin_function(std_df, 3, false, [TYPE_ID, TYPE_PAIR | TYPE_BOOLEAN, CLASS_ANY], FTYPE_FEXPR);
lisp_docs['remd'] = 'explaining what remd is / how it is used!';
lisp_arg_info['remd'] = '[id]';
function std_remd(a, env) {
  var fname = a[0];

  throw new Error('REMD not implemented (yet)');
};
builtins['remd'] = new builtin_function(std_remd, 1, false, [TYPE_ID], FTYPE_EXPR);
lisp_docs['de'] = 'explaining what de is / how it is used!';
lisp_arg_info['de'] = '[id], [pair | boolean], [any]';
function std_de(a, env) {
  var fname = a[0];
  var params = a[1];
  var fn = a[2];

  if (params == T) {
    // throw some error
  }

  var func = new interpreted_function(fn, params, FTYPE_EXPR);

  env.functions.set(fname.prin1(), func);

  return fname;
};
builtins['de'] = new builtin_function(std_de, 3, false, [TYPE_ID, TYPE_PAIR | TYPE_BOOLEAN, CLASS_ANY], FTYPE_FEXPR);
lisp_docs['getd'] = 'explaining what getd is / how it is used!';
lisp_arg_info['getd'] = '[any]';
function std_getd(a, env) {
  var fname = a[0];

  var func = env.functions.get(fname.prin1());

  if (func != UNDEFINED) {
    return new lisp_pair(new lisp_id(ftype_strings[func.ftype], env.oblist), func);
  } else {
    return NIL;
  }
};
builtins['getd'] = new builtin_function(std_getd, 1, false, [CLASS_ANY], FTYPE_EXPR);
lisp_docs['maplist'] = 'explaining what maplist is / how it is used!';
interpreted_builtins['maplist'] = '(de maplist (x fn)\n(cond\n  ((null x) NIL)\n  (T (cons (fn x) (maplist (cdr x) fn)))))';
lisp_docs['map'] = 'explaining what map is / how it is used!';
lisp_arg_info['map'] = '[pair | boolean], [function]';
function std_map(a, env) {
  var x = a[0];
  var fn = a[1];

  if (x == T) {
    throw new Error('***** T is not a list');
  }

  for (var p = x; p != NIL; p = p.cdr) {
    APPLY1(fn, QUOTE(p, env)).evaluate(env);
  }

  return NIL;
};
builtins['map'] = new builtin_function(std_map, 2, false, [TYPE_PAIR | TYPE_BOOLEAN, TYPE_FUNCTION], FTYPE_EXPR);
lisp_docs['mapcan'] = 'explaining what mapcan is / how it is used!';
interpreted_builtins['mapcan'] = '(de mapcan (x fn)\n(cond\n  ((null x) NIL)\n  (T (nconc (fn (car x)) (mapcan (cdr x) fn)))))';
lisp_docs['mapc'] = 'explaining what mapc is / how it is used!';
lisp_arg_info['mapc'] = '[pair | boolean], [function]';
function std_mapc(a, env) {
  var x = a[0];
  var fn = a[1];

  if (x == T) {
    throw new Error('***** T is not a list');
  }

  for (var p = x; p != NIL; p = p.cdr) {
    APPLY1(fn, QUOTE(p.car, env)).evaluate(env);
  }

  return NIL;
};
builtins['mapc'] = new builtin_function(std_mapc, 2, false, [TYPE_PAIR | TYPE_BOOLEAN, TYPE_FUNCTION], FTYPE_EXPR);
lisp_docs['mapcon'] = 'explaining what mapcon is / how it is used!';
interpreted_builtins['mapcon'] = '(de mapcon (x fn)\n(cond\n  ((null x) NIL)\n  (T (nconc (fn x) (mapcon (cdr x) fn)))))';
lisp_docs['mapcar'] = 'explaining what mapcar is / how it is used!';
interpreted_builtins['mapcar'] = '(de mapcar (x fn)\n(cond\n  ((null x) NIL)\n  (T (cons (fn (car x)) (mapcar (cdr x) fn)))))';
lisp_docs['copyvectortofrom'] = 'explaining what copyvectortofrom is / how it is used!';
lisp_arg_info['copyvectortofrom'] = '[vector], [vector]';
std_copyvectortofrom = function(a, env) {
  var newv, oldv;
  newv = a[0];
  oldv = a[1];
  newv.value = oldv.value.slice(0);
  return newv;
};
builtins['copyvectortofrom'] = new builtin_function(std_copyvectortofrom, 2, false, [TYPE_VECTOR, TYPE_VECTOR], FTYPE_EXPR);
lisp_docs['vector-fetch'] = 'explaining what vector-fetch is / how it is used!';
lisp_arg_info['vector-fetch'] = '[vector], [integer]';
std_vector_fetch = function(a, env) {
  var index, v;
  v = a[0].value;
  index = a[1].value;
  return v[index];
};
builtins['vector-fetch'] = new builtin_function(std_vector_fetch, 2, false, [TYPE_VECTOR, TYPE_INTEGER], FTYPE_EXPR);
lisp_docs['putv'] = 'explaining what putv is / how it is used!';
lisp_arg_info['putv'] = '[vector], [integer], [any]';
function std_putv(a, env) {
  var v = a[0].value;
  var index = a[1].value;
  var value = a[2];

  if ((index < 0) && (index > v.length)) {
    throw new Error('***** ' + index + ' subscript is out of range');
  } else {
    v[index] = value;
    return value
  }
};
builtins['putv'] = new builtin_function(std_putv, 3, false, [TYPE_VECTOR, TYPE_INTEGER, CLASS_ANY], FTYPE_EXPR);
lisp_docs['vector-store'] = 'explaining what vector-store is / how it is used!';
lisp_arg_info['vector-store'] = '[vector], [integer], [any]';
std_vector_store = function(a, env) {
  var index, v, value;
  v = a[0].value;
  index = a[1].value;
  value = a[2];
  v[index] = value;
  return value;
};
builtins['vector-store'] = new builtin_function(std_vector_store, 3, false, [TYPE_VECTOR, TYPE_INTEGER, CLASS_ANY], FTYPE_EXPR);
lisp_docs['vector'] = 'explaining what vector is / how it is used!';
lisp_arg_info['vector'] = '[[any]]';
std_vector = function(a, env) {
  var args;
  args = a[0];
  return new lisp_vector(args);
};
builtins['vector'] = new builtin_function(std_vector, 0, true, [CLASS_ANY], FTYPE_EXPR);
lisp_docs['copyvector'] = 'explaining what copyvector is / how it is used!';
lisp_arg_info['copyvector'] = '[vector]';
std_copyvector = function(a, env) {
  var v;
  v = a[0];
  return new lisp_vector(v.value.slice(0));
};
builtins['copyvector'] = new builtin_function(std_copyvector, 1, false, [TYPE_VECTOR], FTYPE_EXPR);
lisp_docs['vector-size'] = 'explaining what vector-size is / how it is used!';
lisp_arg_info['vector-size'] = '[vector]';
std_vector_size = function(a, env) {
  var v;
  v = a[0].value;
  return new lisp_integer(v.length);
};
builtins['vector-size'] = new builtin_function(std_vector_size, 1, false, [TYPE_VECTOR], FTYPE_EXPR);
lisp_docs['vector-upper-bound'] = 'explaining what vector-upper-bound is / how it is used!';
lisp_arg_info['vector-upper-bound'] = '[vector]';
std_vector_upper_bound = function(a, env) {
  var v;
  v = a[0].value;
  return new lisp_integer(v.length - 1);
};
builtins['vector-upper-bound'] = new builtin_function(std_vector_upper_bound, 1, false, [TYPE_VECTOR], FTYPE_EXPR);
lisp_docs['mkvect'] = 'explaining what mkvect is / how it is used!';
lisp_arg_info['mkvect'] = '[integer]';
function std_mkvect(a, env) {
  var uplim = a[0].value;

  if (uplim <= 0) {
    throw new Error('***** A vector of size ' + uplim + 'cannot be allocated');
  }

  var ret = [];
  for (var i = 0; i <= uplim; i++) {
    ret.push(NIL);
  }

  return new lisp_vector(ret);
};
builtins['mkvect'] = new builtin_function(std_mkvect, 1, false, [TYPE_INTEGER], FTYPE_EXPR);
lisp_docs['make-vector'] = 'explaining what make-vector is / how it is used!';
lisp_arg_info['make-vector'] = '[integer], [any]';
std_make_vector = function(a, env) {
  var i, intval, ret, uplim;
  uplim = a[0].value;
  intval = a[1];
  ret = [];
  for (i = 0; 0 <= uplim ? i <= uplim : i >= uplim; 0 <= uplim ? i++ : i--) {
    ret.push(intval);
  }
  return new lisp_vector(ret);
};
builtins['make-vector'] = new builtin_function(std_make_vector, 2, false, [TYPE_INTEGER, CLASS_ANY], FTYPE_EXPR);
lisp_docs['getv'] = 'explaining what getv is / how it is used!';
lisp_arg_info['getv'] = '[vector], [integer]';
function std_getv(a, env) {
  var v = a[0].value;
  var index = a[1].value;

  var ret = v[index];
  if (ret == undefined) {
    throw new Error('***** ' + index + ' subscript is out of range');
  } else {
    return ret;
  }
};
builtins['getv'] = new builtin_function(std_getv, 2, false, [TYPE_VECTOR, TYPE_INTEGER], FTYPE_EXPR);
lisp_docs['upbv'] = 'explaining what upbv is / how it is used!';
lisp_arg_info['upbv'] = '[any]';
function std_upbv(a, env) {
  var u = a[0];

  if (type_check(u.type, TYPE_VECTOR)) {
    return new lisp_integer(u.value.length - 1);
  } else {
    return NIL;
  }
};
builtins['upbv'] = new builtin_function(std_upbv, 1, false, [CLASS_ANY], FTYPE_EXPR);
lisp_docs['string-split'] = 'explaining what string-split is / how it is used!';
lisp_arg_info['string-split'] = '[string], [string]';
std_string_split = function(a, env) {
  var del, s, str;
  str = a[0].value;
  del = a[1].value;
  return array_to_list((function() {
    var _i, _len, _ref, _results;
    _ref = str.split(del);
    _results = [];
    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
      s = _ref[_i];
      _results.push(new lisp_string(s));
    }
    return _results;
  })());
};
builtins['string-split'] = new builtin_function(std_string_split, 2, false, [TYPE_STRING, TYPE_STRING], FTYPE_EXPR);
lisp_docs['string-store'] = 'explaining what string-store is / how it is used!';
lisp_arg_info['string-store'] = '[string], [integer], [integer]';
std_string_store = function(a, env) {
  var chr, index, str;
  str = a[0];
  index = a[1].value.toJSValue();
  chr = String.fromCharCode(a[2].value.toJSValue());
  str.value = str.value.slice(0, index) + chr + str.value.slice(index + 1);
  return str;
};
builtins['string-store'] = new builtin_function(std_string_store, 3, false, [TYPE_STRING, TYPE_INTEGER, TYPE_INTEGER], FTYPE_EXPR);
lisp_docs['string'] = 'explaining what string is / how it is used!';
lisp_arg_info['string'] = '[[integer]]';
std_string = function(a, env) {
  var c, ret, vals, _i, _len;
  vals = a[0];
  ret = '';
  for (_i = 0, _len = vals.length; _i < _len; _i++) {
    c = vals[_i];
    ret += String.fromCharCode(c.value.toJSValue());
  }
  return new lisp_string(ret);
};
builtins['string'] = new builtin_function(std_string, 0, true, [TYPE_INTEGER], FTYPE_EXPR);
lisp_docs['string-upcase'] = 'explaining what string-upcase is / how it is used!';
lisp_arg_info['string-upcase'] = '[string]';
std_string_upcase = function(a, env) {
  var str;
  str = a[0].value;
  return new lisp_string(str.toUpperCase());
};
builtins['string-upcase'] = new builtin_function(std_string_upcase, 1, false, [TYPE_STRING], FTYPE_EXPR);
lisp_docs['string-repeat'] = 'explaining what string-repeat is / how it is used!';
lisp_arg_info['string-repeat'] = '[string], [integer]';
std_string_repeat = function(a, env) {
  var i, ret, str;
  str = a[0].value;
  i = a[1].value.subtract(1);
  ret = str;
  while (!i.isZero()) {
    ret += str;
    i = i.subtract(1);
  }
  return new lisp_string(ret);
};
builtins['string-repeat'] = new builtin_function(std_string_repeat, 2, false, [TYPE_STRING, TYPE_INTEGER], FTYPE_EXPR);
lisp_docs['string2list'] = 'synonymous with string-to-list';
lisp_docs['string-to-list'] = 'explaining what string-to-list is / how it is used!';
lisp_arg_info['string-to-list'] = '[string]';
lisp_arg_info['string2list'] = lisp_arg_info['string-to-list'];
std_string_to_list = function(a, env) {
  var i, str;
  str = a[0].value;
  return array_to_list((function() {
    var _ref, _results;
    _results = [];
    for (i = 0, _ref = str.length; 0 <= _ref ? i < _ref : i > _ref; 0 <= _ref ? i++ : i--) {
      _results.push(new lisp_integer(str.charCodeAt(i)));
    }
    return _results;
  })());
};
builtins['string-to-list'] = new builtin_function(std_string_to_list, 1, false, [TYPE_STRING], FTYPE_EXPR);
builtins['string2list'] = builtins['string-to-list'];
lisp_docs['string-length'] = 'explaining what string-length is / how it is used!';
lisp_arg_info['string-length'] = '[string]';
std_string_length = function(a, env) {
  var str;
  str = a[0].value;
  return new lisp_integer(str.length);
};
builtins['string-length'] = new builtin_function(std_string_length, 1, false, [TYPE_STRING], FTYPE_EXPR);
lisp_docs['substring'] = 'explaining what substring is / how it is used!';
lisp_arg_info['substring'] = '[string], [integer], [integer]';
std_substring = function(a, env) {
  var end, start, str;
  str = a[0].value;
  start = a[1].value.toJSValue();
  end = a[2].value.toJSValue();
  return new lisp_string(str.substr(start, end));
};
builtins['substring'] = new builtin_function(std_substring, 3, false, [TYPE_STRING, TYPE_INTEGER, TYPE_INTEGER], FTYPE_EXPR);
lisp_docs['string-downcase'] = 'explaining what string-downcase is / how it is used!';
lisp_arg_info['string-downcase'] = '[string]';
std_string_downcase = function(a, env) {
  var str;
  str = a[0].value;
  return new lisp_string(str.toLowerCase());
};
builtins['string-downcase'] = new builtin_function(std_string_downcase, 1, false, [TYPE_STRING], FTYPE_EXPR);
lisp_docs['nstring-upcase'] = 'explaining what nstring-upcase is / how it is used!';
lisp_arg_info['nstring-upcase'] = '[string]';
std_nstring_upcase = function(a, env) {
  var str;
  str = a[0];
  str.value = str.value.toUpperCase();
  return str;
};
builtins['nstring-upcase'] = new builtin_function(std_nstring_upcase, 1, false, [TYPE_STRING], FTYPE_EXPR);
lisp_docs['nstring-downcase'] = 'explaining what nstring-downcase is / how it is used!';
lisp_arg_info['nstring-downcase'] = '[string]';
std_nstring_downcase = function(a, env) {
  var str;
  str = a[0];
  str.value = str.value.toLowerCase();
  return str;
};
builtins['nstring-downcase'] = new builtin_function(std_nstring_downcase, 1, false, [TYPE_STRING], FTYPE_EXPR);
lisp_docs['allocate-string'] = 'explaining what allocate-string is / how it is used!';
lisp_arg_info['allocate-string'] = '[integer]';
std_allocate_string = function(a, env) {
  var length, ret;
  length = a[0].value;
  ret = '';
  while (!length.isZero()) {
    ret += ' ';
    length = length.subtract(1);
  }
  return new lisp_string(ret);
};
builtins['allocate-string'] = new builtin_function(std_allocate_string, 1, false, [TYPE_INTEGER], FTYPE_EXPR);
lisp_docs['mkstring'] = 'explaining what mkstring is / how it is used!';
lisp_arg_info['mkstring'] = '[integer], [integer]';
std_mkstring = function(a, env) {
  var initval, length, ret;
  length = a[0].value.add(1);
  initval = String.fromCharCode(a[1].value.toJSValue());
  ret = '';
  while (!length.isZero()) {
    ret += initval;
    length = length.subtract(1);
  }
  return new lisp_string(ret);
};
builtins['mkstring'] = new builtin_function(std_mkstring, 2, false, [TYPE_INTEGER, TYPE_INTEGER], FTYPE_EXPR);
lisp_docs['string-fetch'] = 'explaining what string-fetch is / how it is used!';
lisp_arg_info['string-fetch'] = '[string], [integer]';
std_string_fetch = function(a, env) {
  var index, str;
  str = a[0].value;
  index = a[1].value.toJSValue();
  return new lisp_integer(str.charCodeAt(index));
};
builtins['string-fetch'] = new builtin_function(std_string_fetch, 2, false, [TYPE_STRING, TYPE_INTEGER], FTYPE_EXPR);
lisp_docs['string-upper-bound'] = 'explaining what string-upper-bound is / how it is used!';
lisp_arg_info['string-upper-bound'] = '[string]';
std_string_upper_bound = function(a, env) {
  var str;
  str = a[0].value;
  return new lisp_integer(str.length - 1);
};
builtins['string-upper-bound'] = new builtin_function(std_string_upper_bound, 1, false, [TYPE_STRING], FTYPE_EXPR);
lisp_docs['make-string'] = 'explaining what make-string is / how it is used!';
lisp_arg_info['make-string'] = '[integer], [integer]';
std_make_string = function(a, env) {
  var initval, length, ret;
  length = a[0].value;
  initval = String.fromCharCode(a[1].value.toJSValue());
  ret = '';
  while (!length.isZero()) {
    ret += initval;
    length = length.subtract(1);
  }
  return new lisp_string(ret);
};
builtins['make-string'] = new builtin_function(std_make_string, 2, false, [TYPE_INTEGER, TYPE_INTEGER], FTYPE_EXPR);
lisp_docs['string-concat'] = 'explaining what string-concat is / how it is used!';
lisp_arg_info['string-concat'] = '[[string]]';
std_string_concat = function(a, env) {
  var ret, s, strs, _i, _len;
  strs = a[0];
  ret = '';
  for (_i = 0, _len = strs.length; _i < _len; _i++) {
    s = strs[_i];
    ret += s.value;
  }
  return new lisp_string(ret);
};
builtins['string-concat'] = new builtin_function(std_string_concat, 0, true, [TYPE_STRING], FTYPE_EXPR);
lisp_docs['copystringtofrom'] = 'explaining what copystringtofrom is / how it is used!';
lisp_arg_info['copystringtofrom'] = '[string], [string]';
std_copystringtofrom = function(a, env) {
  var newstr, oldstr;
  newstr = a[0];
  oldstr = a[1];
  newstr.value = oldstr.value;
  return newstr;
};
builtins['copystringtofrom'] = new builtin_function(std_copystringtofrom, 2, false, [TYPE_STRING, TYPE_STRING], FTYPE_EXPR);
lisp_docs['copystring'] = 'explaining what copystring is / how it is used!';
lisp_arg_info['copystring'] = '[string]';
std_copystring = function(a, env) {
  var str;
  str = a[0];
  return new lisp_string(str.value);
};
builtins['copystring'] = new builtin_function(std_copystring, 1, false, [TYPE_STRING], FTYPE_EXPR);
lisp_docs['string2vector'] = 'synonymous with string-to-vector';
lisp_docs['string-to-vector'] = 'explaining what string-to-vector is / how it is used!';
lisp_arg_info['string-to-vector'] = '[string]';
lisp_arg_info['string2vector'] = lisp_arg_info['string-to-vector'];
std_string_to_vector = function(a, env) {
  var i, str;
  str = a[0].value;
  return new lisp_vector((function() {
    var _ref, _results;
    _results = [];
    for (i = 0, _ref = str.length; 0 <= _ref ? i < _ref : i > _ref; 0 <= _ref ? i++ : i--) {
      _results.push(new lisp_integer(str.charCodeAt(i)));
    }
    return _results;
  })());
};
builtins['string-to-vector'] = new builtin_function(std_string_to_vector, 1, false, [TYPE_STRING], FTYPE_EXPR);
builtins['string2vector'] = builtins['string-to-vector'];
lisp_docs['string-trim'] = 'explaining what string-trim is / how it is used!';
lisp_arg_info['string-trim'] = '[pair | string], [string]';
std_string_trim = function(a, env) {
  var bag, i, str, _ref, _ref2;
  bag = a[0];
  str = a[1].value;
  if (bag.type === TYPE_PAIR) {
    bag = list_to_array(bag);
  } else if (bag.type === TYPE_STRING) {
    bag = (function() {
      var _ref, _results;
      _results = [];
      for (i = 0, _ref = bag.value.length; 0 <= _ref ? i < _ref : i > _ref; 0 <= _ref ? i++ : i--) {
        _results.push(bag.value.charCodeAt(i));
      }
      return _results;
    })();
  }
  while (_ref = str.charCodeAt(0), __indexOf.call(bag, _ref) >= 0) {
    str = str.slice(1);
  }
  while (_ref2 = str.charCodeAt(str.length - 1), __indexOf.call(bag, _ref2) >= 0) {
    str = str.substr(0, str.length - 1);
  }
  return new lisp_string(str);
};
builtins['string-trim'] = new builtin_function(std_string_trim, 2, false, [TYPE_PAIR | TYPE_STRING, TYPE_STRING], FTYPE_EXPR);
lisp_docs['string-left-trim'] = 'explaining what string-left-trim is / how it is used!';
lisp_arg_info['string-left-trim'] = '[pair | string], [string]';
std_string_left_trim = function(a, env) {
  var bag, i, str, _ref;
  bag = a[0];
  str = a[1].value;
  if (bag.type === TYPE_PAIR) {
    bag = list_to_array(bag);
  } else if (bag.type === TYPE_STRING) {
    bag = (function() {
      var _ref, _results;
      _results = [];
      for (i = 0, _ref = bag.value.length; 0 <= _ref ? i < _ref : i > _ref; 0 <= _ref ? i++ : i--) {
        _results.push(bag.value.charCodeAt(i));
      }
      return _results;
    })();
  }
  while (_ref = str.charCodeAt(0), __indexOf.call(bag, _ref) >= 0) {
    str = str.slice(1);
  }
  return new lisp_string(str);
};
builtins['string-left-trim'] = new builtin_function(std_string_left_trim, 2, false, [TYPE_PAIR | TYPE_STRING, TYPE_STRING], FTYPE_EXPR);
lisp_docs['string-right-trim'] = 'explaining what string-right-trim is / how it is used!';
lisp_arg_info['string-right-trim'] = '[pair | string], [string]';
std_string_right_trim = function(a, env) {
  var bag, i, str, _ref;
  bag = a[0];
  str = a[1].value;
  if (bag.type === TYPE_PAIR) {
    bag = list_to_array(bag);
  } else if (bag.type === TYPE_STRING) {
    bag = (function() {
      var _ref, _results;
      _results = [];
      for (i = 0, _ref = bag.value.length; 0 <= _ref ? i < _ref : i > _ref; 0 <= _ref ? i++ : i--) {
        _results.push(bag.value.charCodeAt(i));
      }
      return _results;
    })();
  }
  while (_ref = str.charCodeAt(str.length - 1), __indexOf.call(bag, _ref) >= 0) {
    str = str.substr(0, str.length - 1);
  }
  return new lisp_string(str);
};
builtins['string-right-trim'] = new builtin_function(std_string_right_trim, 2, false, [TYPE_PAIR | TYPE_STRING, TYPE_STRING], FTYPE_EXPR);
lisp_docs['digit'] = 'explaining what digit is / how it is used!';
interpreted_builtins['digit'] = '(de digit (u)\n(if (memq u \'(!0 !1 !2 !3 !4 !5 !6 !7 !8 !9))\n  t\n  nil))';
lisp_docs['liter'] = 'explaining what liter is / how it is used!';
interpreted_builtins['liter'] = '(de liter (u)\n(if (memq u \'(!A !B !C !D !E !F !G !H !I !J !K !L !M\n              !N !O !P !Q !R !S !T !U !V !W !X !Y !Z\n              !a !b !c !d !e !f !g !h !i !j !k !l !m\n              !n !o !p !q !r !s !t !u !v !w !x !y !z))\n  t\n  nil))';
lisp_docs['nconc'] = 'explaining what nconc is / how it is used!';
interpreted_builtins['nconc'] = '(de nconc (u v)\n(prog (w)\n  (cond ((null u) (return v)))\n  (setq w u)\n  (prog NIL\ntop   (cond ((null (cdr w)) (return NIL)))\n    (setq w (cdr w))\n    (go top))\n  (rplacd w v)\n  (return u)))';
lisp_docs['id-sort'] = 'explaining what id-sort is / how it is used!';
lisp_arg_info['id-sort'] = '[pair]';
std_id_sort = function(a, env) {
  var e, table;
  table = (function() {
    var _i, _len, _ref, _results;
    _ref = list_to_array(a[0]);
    _results = [];
    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
      e = _ref[_i];
      _results.push(e.value);
    }
    return _results;
  })();
  table.sort();
  return array_to_list((function() {
    var _i, _len, _results;
    _results = [];
    for (_i = 0, _len = table.length; _i < _len; _i++) {
      e = table[_i];
      _results.push(new lisp_id(e, env.oblist));
    }
    return _results;
  })());
};
builtins['id-sort'] = new builtin_function(std_id_sort, 1, false, [TYPE_PAIR], FTYPE_EXPR);
lisp_docs['assoc'] = 'explaining what assoc is / how it is used!';
interpreted_builtins['assoc'] = '(de assoc (u v)\n(cond\n  ((null v) NIL)\n  ((atom (car v)) (error 0 (list v "is a poorly formed alist")))\n  ((equal u (caar v)) (car v))\n  (T (assoc u (cdr v)))))';
lisp_docs['pair'] = 'explaining what pair is / how it is used!';
interpreted_builtins['pair'] = '(de pair (u v)\n(cond\n  ((and u v) (cons (cons (car u) (car v)) (pair (cdr u) (cdr v))))\n  ((or u v) (error 0 "different length lists in pair"))\n  (T NIL)))';
lisp_docs['append'] = 'explaining what append is / how it is used!';
interpreted_builtins['append'] = '(de append (u v)\n(cond\n  ((null u) v)\n  (T (cons (car u) (append (cdr u) v)))))';
lisp_docs['deflist'] = 'explaining what deflist is / how it is used!';
interpreted_builtins['deflist'] = '(de deflist (u ind)\n(cond\n  ((null u) NIL)\n  (T (cons\n      (progn\n        (put (caar u) ind (cadar u))\n        (caar u))\n      (deflist (cdr u) ind)))))';
lisp_docs['reverse'] = 'explaining what reverse is / how it is used!';
lisp_arg_info['reverse'] = '[pair]';
function std_reverse(a, env) {
  var u = a[0];

  var elements = [];
  for (var p = u; p != NIL; p = p.cdr) {
    elements.push(p.car);
  }

  var head = new lisp_pair(elements[elements.length - 1], NIL);
  var ptr = head;

  for (var i = elements.length - 2; i >= 0; i--) {
    ptr.cdr = new lisp_pair(elements[i], NIL);
    ptr = ptr.cdr;
  }

  return head;
};
builtins['reverse'] = new builtin_function(std_reverse, 1, false, [TYPE_PAIR], FTYPE_EXPR);
lisp_docs['sublis'] = 'explaining what sublis is / how it is used!';
interpreted_builtins['sublis'] = '(de sublis (x y)\n(cond\n  ((null x) y)\n  (T (prog (u)\n      (setq u (assoc y x))\n      (return\n        (cond\n          ((not (null u)) (cdr u))\n          ((atom y) y)\n          (T (cons (sublis x (car y)) (sublis x (cdr y))))))))))';
lisp_docs['subst'] = 'explaining what subst is / how it is used!';
interpreted_builtins['subst'] = '(de subst (u v w)\n(cond\n  ((null w) NIL)\n  ((equal v w) u)\n  ((atom w) w)\n  (T (cons (subst u v (car w)) (subst u v (cdr w))))))';
lisp_docs['member'] = 'explaining what member is / how it is used!';
interpreted_builtins['member'] = '(de member (a b)\n(cond\n  ((null b) NIL)\n  ((equal a (car b)) b)\n  (T (member a (cdr b)))))';
lisp_docs['length'] = 'explaining what length is / how it is used!';
lisp_arg_info['length'] = '[any]';
function std_length(a, env) {
  var x = a[0];

  var length = 0;
  for (var p = x; p != NIL; p = p.cdr) {
    length++;
  }

  return new lisp_integer(BigInteger(length));
};
builtins['length'] = new builtin_function(std_length, 1, false, [CLASS_ANY], FTYPE_EXPR);
lisp_docs['memq'] = 'explaining what memq is / how it is used!';
interpreted_builtins['memq'] = '(de memq (a b)\n(cond\n  ((null b) NIL)\n  ((eq a (car b)) b)\n  (T (memq a (cdr b)))))';
lisp_docs['sassoc'] = 'explaining what sassoc is / how it is used!';
interpreted_builtins['sassoc'] = '(de sassoc (u v fn)\n(cond\n  ((null v) (fn))\n  ((equal u (caar v)) (car v))\n  (T (sassoc u (cdr v) fn))))';
lisp_docs['delete'] = 'explaining what delete is / how it is used!';
interpreted_builtins['delete'] = '(de delete (u v)\n(cond\n  ((null v) NIL)\n  ((equal (car v) u) (cdr v))\n  (T (cons (car v) (delete u (cdr v))))))';
lisp_docs['help'] = 'if TOPICS is not provided, help returns a list of the id\'s for which there is help information; otherwise, help returns a list composed of the help  information for each element of TOPICS.';
lisp_arg_info['help'] = '[TOPICS [id]]';
std_help = function(a, env) {
  var topic, topics;
  topics = a[0];
  if (topics.length === 0) {
    return array_to_list((function() {
      var _results;
      _results = [];
      for (topic in lisp_docs) {
        _results.push(new lisp_id(topic, env.oblist));
      }
      return _results;
    })());
  } else {
    return array_to_list((function() {
      var _i, _len, _results;
      _results = [];
      for (_i = 0, _len = topics.length; _i < _len; _i++) {
        topic = topics[_i];
        _results.push(new lisp_string((topic.value in lisp_docs ? lisp_docs[topic.value] : "no help for " + topic.value)));
      }
      return _results;
    })());
    return array_to_list((function() {
      var _i, _len, _ref, _results;
      _results = [];
      for (_i = 0, _len = topics.length; _i < _len; _i++) {
        topic = topics[_i];
        _results.push(((_ref = topic.value, __indexOf.call(lisp_docs, _ref) >= 0) ? new lisp_string(lisp_docs[topic.value]) : "no help for " + topic.value));
      }
      return _results;
    })());
  }
};
builtins['help'] = new builtin_function(std_help, 0, true, [TYPE_ID], FTYPE_EXPR);
lisp_docs['random'] = 'explaining what random is / how it is used!';
lisp_arg_info['random'] = '[integer]';
std_random = function(a, env) {
  var uplim;
  uplim = a[0].value.toJSValue();
  return new lisp_integer(Math.floor(Math.random() * uplim));
};
builtins['random'] = new builtin_function(std_random, 1, false, [TYPE_INTEGER], FTYPE_EXPR);
lisp_docs['pop'] = 'explaining what pop is / how it is used!';
interpreted_builtins['pop'] = '(dm pop (u)\n(let ((stack (second u))\n       (where (third u)))\n  (if (null where)\n    `(prog (val)\n       (setq val (car ,stack))\n       (setq ,stack (cdr ,stack))\n       (return val))\n    `(progn (setq ,where (car ,stack))\n                (setq ,stack (cdr ,stack))\n                ,where))))';
lisp_docs['alert'] = 'calls the JavaScript function alert with the prin2 value of MESSAGE. returns NIL';
lisp_arg_info['alert'] = 'MESSAGE [any]';
std_alert = function(a, env) {
  alert(a[0].prin2());
  return NIL;
};
builtins['alert'] = new builtin_function(std_alert, 1, false, [CLASS_ANY], FTYPE_EXPR);
lisp_docs['date'] = 'explaining what date is / how it is used!';
function std_date(a, env) {
  return new lisp_string(new Date());
};
builtins['date'] = new builtin_function(std_date, 0, false, [], FTYPE_EXPR);
lisp_docs['arg-info'] = 'explaining what arg-info is / how it is used!';
lisp_arg_info['arg-info'] = '[id]';
std_arg_info = function(a, env) {
  var func, topic;
  topic = a[0].value;
  if (topic in lisp_arg_info) {
    return new lisp_string(lisp_arg_info[topic]);
  } else {
    func = env.functions.get(topic);
    if (func !== UNDEFINED) {
      return T;
    } else {
      return NIL;
    }
  }
};
builtins['arg-info'] = new builtin_function(std_arg_info, 1, false, [TYPE_ID], FTYPE_EXPR);
lisp_docs['time'] = 'explaining what time is / how it is used!';
function std_time(a, env) {
  return new lisp_integer(Math.round(new Date().getTime()/1000));
};
builtins['time'] = new builtin_function(std_time, 0, false, [], FTYPE_EXPR);
lisp_docs['push'] = 'explaining what push is / how it is used!';
interpreted_builtins['push'] = '(dm push (u)\n(let ((val (second u))\n       (stack (third u)))\n  `(setq ,stack (cons ,val ,stack))))';
lisp_docs['lambda'] = 'explaining what lambda is / how it is used!';
lisp_arg_info['lambda'] = '[pair | boolean], [any]';
function std_lambda(a, env) {
  var args = a[0];
  var expr = a[1];

  if (args == T) {
    // throw some error
  }

  return new interpreted_function(expr, args, FTYPE_EXPR, env);
};
builtins['lambda'] = new builtin_function(std_lambda, 2, false, [TYPE_PAIR | TYPE_BOOLEAN, CLASS_ANY], FTYPE_FEXPR);
lisp_docs['js-obj?'] = 'explaining what js-obj? is / how it is used!';
lisp_arg_info['js-obj?'] = 'U [any]';
std_js_objqmark = function(a, env) {
  var u;
  u = a[0];
  if (u.type === TYPE_JS_OBJ) {
    return T;
  } else {
    return NIL;
  }
};
builtins['js-obj?'] = new builtin_function(std_js_objqmark, 1, false, [CLASS_ANY], FTYPE_EXPR);
lisp_docs['js-method-call'] = 'explaining what js-method-call is / how it is used!';
lisp_arg_info['js-method-call'] = 'OBJECT [js_obj], [METHOD [string]]';
std_js_method_call = function(a, env) {
  var args, e, method, obj;
  obj = a[0].value;
  method = a[1].value;
  args = (function() {
    var _i, _len, _ref, _results;
    _ref = a[2];
    _results = [];
    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
      e = _ref[_i];
      _results.push(lisp_to_js(e));
    }
    return _results;
  })();
  return js_to_lisp(obj[method].apply(obj, args));
};
builtins['js-method-call'] = new builtin_function(std_js_method_call, 2, true, [TYPE_JS_OBJ, TYPE_STRING, CLASS_ANY], FTYPE_EXPR);
lisp_docs['js-eval'] = 'explaining what js-eval is / how it is used!';
lisp_arg_info['js-eval'] = '[string]';
std_js_eval = function(a, env) {
  var expr;
  expr = a[0].value;
  return js_to_lisp(eval(expr));
};
builtins['js-eval'] = new builtin_function(std_js_eval, 1, false, [TYPE_STRING], FTYPE_EXPR);
lisp_docs['js-get'] = 'explaining what js-get is / how it is used!';
lisp_arg_info['js-get'] = 'OBJECT [js], PROPERTY [string]';
std_js_get = function(a, env) {
  var obj, property, val;
  obj = a[0].value;
  property = a[1].value;
  val = js_to_lisp(obj[property]);
  if (val.type === TYPE_JS_FUNC) {
    val.scope = obj;
  }
  return val;
};
builtins['js-get'] = new builtin_function(std_js_get, 2, false, [CLASS_JS, TYPE_STRING], FTYPE_EXPR);
lisp_docs['js-set'] = 'explaining what js-set is / how it is used!';
lisp_arg_info['js-set'] = 'OBJECT [js], PROPERTY [string], VALUE [any]';
std_js_set = function(a, env) {
  var obj, property, val;
  obj = a[0].value;
  property = a[1].value;
  val = a[2];
  obj[property] = lisp_to_js(val);
  return val;
};
builtins['js-set'] = new builtin_function(std_js_set, 3, false, [CLASS_JS, TYPE_STRING, CLASS_ANY], FTYPE_EXPR);
lisp_docs['js-apply'] = 'explaining what js-apply is / how it is used!';
lisp_arg_info['js-apply'] = '[FUNCTION [js_func]]';
std_js_apply = function(a, env) {
  var args, e, func, ret;
  func = a[0].value;
  args = (function() {
    var _i, _len, _ref, _results;
    _ref = a[1];
    _results = [];
    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
      e = _ref[_i];
      _results.push(lisp_to_js(e));
    }
    return _results;
  })();
  ret = js_to_lisp(func.apply(func.scope, args));
  return ret;
};
builtins['js-apply'] = new builtin_function(std_js_apply, 1, true, [TYPE_JS_FUNC, CLASS_ANY], FTYPE_EXPR);
lisp_docs['second'] = 'synonymous with cadr';
lisp_docs['cadr'] = '(cadr u) is equivalent to (car (cdr u))';
lisp_arg_info['cadr'] = '[pair | boolean]';
lisp_arg_info['second'] = lisp_arg_info['cadr'];
function std_cadr(a, env) {
  var u = a[0];

  if (u == T) {
    throw new Error('***** T is not a list');
  }

  return u.cdr.car;
};
builtins['cadr'] = new builtin_function(std_cadr, 1, false, [TYPE_PAIR | TYPE_BOOLEAN], FTYPE_EXPR);
builtins['second'] = builtins['cadr'];
lisp_docs['cons'] = 'explaining what cons is / how it is used!';
lisp_arg_info['cons'] = '[any], [any]';
function std_cons(a, env) {
  var u = a[0];
  var v = a[1];

  return new lisp_pair(u, v);
};
builtins['cons'] = new builtin_function(std_cons, 2, false, [CLASS_ANY, CLASS_ANY], FTYPE_EXPR);
lisp_docs['cdddar'] = '(cdddar u) is equivalent to (cdr (cdr (cdr (car u))))';
lisp_arg_info['cdddar'] = '[pair | boolean]';
function std_cdddar(a, env) {
  var u = a[0];

  if (u == T) {
    throw new Error('***** T is not a list');
  }

  return u.car.cdr.cdr.cdr;
};
builtins['cdddar'] = new builtin_function(std_cdddar, 1, false, [TYPE_PAIR | TYPE_BOOLEAN], FTYPE_EXPR);
lisp_docs['cadar'] = '(cadar u) is equivalent to (car (cdr (car u)))';
lisp_arg_info['cadar'] = '[pair | boolean]';
function std_cadar(a, env) {
  var u = a[0];

  if (u == T) {
    throw new Error('***** T is not a list');
  }

  return u.car.cdr.car;
};
builtins['cadar'] = new builtin_function(std_cadar, 1, false, [TYPE_PAIR | TYPE_BOOLEAN], FTYPE_EXPR);
lisp_docs['caaaar'] = '(caaaar u) is equivalent to (car (car (car (car u))))';
lisp_arg_info['caaaar'] = '[pair | boolean]';
function std_caaaar(a, env) {
  var u = a[0];

  if (u == T) {
    throw new Error('***** T is not a list');
  }

  return u.car.car.car.car;
};
builtins['caaaar'] = new builtin_function(std_caaaar, 1, false, [TYPE_PAIR | TYPE_BOOLEAN], FTYPE_EXPR);
lisp_docs['cddar'] = '(cddar u) is equivalent to (cdr (cdr (car u)))';
lisp_arg_info['cddar'] = '[pair | boolean]';
function std_cddar(a, env) {
  var u = a[0];

  if (u == T) {
    throw new Error('***** T is not a list');
  }

  return u.car.cdr.cdr;
};
builtins['cddar'] = new builtin_function(std_cddar, 1, false, [TYPE_PAIR | TYPE_BOOLEAN], FTYPE_EXPR);
lisp_docs['caadar'] = '(caadar u) is equivalent to (car (car (cdr (car u))))';
lisp_arg_info['caadar'] = '[pair | boolean]';
function std_caadar(a, env) {
  var u = a[0];

  if (u == T) {
    throw new Error('***** T is not a list');
  }

  return u.car.cdr.car.car;
};
builtins['caadar'] = new builtin_function(std_caadar, 1, false, [TYPE_PAIR | TYPE_BOOLEAN], FTYPE_EXPR);
lisp_docs['cdadr'] = '(cdadr u) is equivalent to (cdr (car (cdr u)))';
lisp_arg_info['cdadr'] = '[pair | boolean]';
function std_cdadr(a, env) {
  var u = a[0];

  if (u == T) {
    throw new Error('***** T is not a list');
  }

  return u.cdr.car.cdr;
};
builtins['cdadr'] = new builtin_function(std_cdadr, 1, false, [TYPE_PAIR | TYPE_BOOLEAN], FTYPE_EXPR);
lisp_docs['rest'] = 'synonymous with cdr';
lisp_docs['cdr'] = 'explaining what cdr is / how it is used!';
lisp_arg_info['cdr'] = '[pair | boolean]';
lisp_arg_info['rest'] = lisp_arg_info['cdr'];
function std_cdr(a, env) {
  var u = a[0];

  if (u == T) {
    throw new Error('***** T is not a list');
  }

  return u.cdr;
};
builtins['cdr'] = new builtin_function(std_cdr, 1, false, [TYPE_PAIR | TYPE_BOOLEAN], FTYPE_EXPR);
builtins['rest'] = builtins['cdr'];
lisp_docs['cdaaar'] = '(cdaaar u) is equivalent to (cdr (car (car (car u))))';
lisp_arg_info['cdaaar'] = '[pair | boolean]';
function std_cdaaar(a, env) {
  var u = a[0];

  if (u == T) {
    throw new Error('***** T is not a list');
  }

  return u.car.car.car.cdr;
};
builtins['cdaaar'] = new builtin_function(std_cdaaar, 1, false, [TYPE_PAIR | TYPE_BOOLEAN], FTYPE_EXPR);
lisp_docs['caaadr'] = '(caaadr u) is equivalent to (car (car (car (cdr u))))';
lisp_arg_info['caaadr'] = '[pair | boolean]';
function std_caaadr(a, env) {
  var u = a[0];

  if (u == T) {
    throw new Error('***** T is not a list');
  }

  return u.cdr.car.car.car;
};
builtins['caaadr'] = new builtin_function(std_caaadr, 1, false, [TYPE_PAIR | TYPE_BOOLEAN], FTYPE_EXPR);
lisp_docs['fifth'] = 'equivalent to (car (cddddr u))';
interpreted_builtins['fifth'] = '(de fifth (u)\n(car (cddddr u)))';
lisp_docs['cddadr'] = '(cddadr u) is equivalent to (cdr (cdr (car (cdr u))))';
lisp_arg_info['cddadr'] = '[pair | boolean]';
function std_cddadr(a, env) {
  var u = a[0];

  if (u == T) {
    throw new Error('***** T is not a list');
  }

  return u.cdr.car.cdr.cdr;
};
builtins['cddadr'] = new builtin_function(std_cddadr, 1, false, [TYPE_PAIR | TYPE_BOOLEAN], FTYPE_EXPR);
lisp_docs['nthcdr'] = 'synonymous with pnth';
lisp_docs['pnth'] = 'returns the zero indexed I\'th cdr of L';
interpreted_builtins['pnth'] = '(de pnth (i l)\n(cond ((eqn i 0) l)\n      (t (pnth (sub1 i) (cdr l)))))';
interpreted_builtins['nthcdr'] = '(dm nthcdr (u) `(pnth ,@(rest u)))';
lisp_docs['caaar'] = '(caaar u) is equivalent to (car (car (car u)))';
lisp_arg_info['caaar'] = '[pair | boolean]';
function std_caaar(a, env) {
  var u = a[0];

  if (u == T) {
    throw new Error('***** T is not a list');
  }

  return u.car.car.car;
};
builtins['caaar'] = new builtin_function(std_caaar, 1, false, [TYPE_PAIR | TYPE_BOOLEAN], FTYPE_EXPR);
lisp_docs['butlast'] = 'butlast';
interpreted_builtins['butlast'] = '(de butlast (l)\n(reverse (cdr (reverse l))))';
lisp_docs['caddar'] = '(caddar u) is equivalent to (car (cdr (cdr (car u))))';
lisp_arg_info['caddar'] = '[pair | boolean]';
function std_caddar(a, env) {
  var u = a[0];

  if (u == T) {
    throw new Error('***** T is not a list');
  }

  return u.car.cdr.cdr.car;
};
builtins['caddar'] = new builtin_function(std_caddar, 1, false, [TYPE_PAIR | TYPE_BOOLEAN], FTYPE_EXPR);
lisp_docs['cadaar'] = '(cadaar u) is equivalent to (car (cdr (car (car u))))';
lisp_arg_info['cadaar'] = '[pair | boolean]';
function std_cadaar(a, env) {
  var u = a[0];

  if (u == T) {
    throw new Error('***** T is not a list');
  }

  return u.car.car.cdr.car;
};
builtins['cadaar'] = new builtin_function(std_cadaar, 1, false, [TYPE_PAIR | TYPE_BOOLEAN], FTYPE_EXPR);
lisp_docs['caar'] = '(caar u) is equivalent to (car (car u))';
lisp_arg_info['caar'] = '[pair | boolean]';
function std_caar(a, env) {
  var u = a[0];

  if (u == T) {
    throw new Error('***** T is not a list');
  }

  return u.car.car;
};
builtins['caar'] = new builtin_function(std_caar, 1, false, [TYPE_PAIR | TYPE_BOOLEAN], FTYPE_EXPR);
lisp_docs['cdddr'] = '(cdddr u) is equivalent to (cdr (cdr (cdr u)))';
lisp_arg_info['cdddr'] = '[pair | boolean]';
function std_cdddr(a, env) {
  var u = a[0];

  if (u == T) {
    throw new Error('***** T is not a list');
  }

  return u.cdr.cdr.cdr;
};
builtins['cdddr'] = new builtin_function(std_cdddr, 1, false, [TYPE_PAIR | TYPE_BOOLEAN], FTYPE_EXPR);
lisp_docs['fourth'] = 'synonymous with cadddr';
lisp_docs['cadddr'] = '(cadddr u) is equivalent to (car (cdr (cdr (cdr u))))';
lisp_arg_info['cadddr'] = '[pair | boolean]';
lisp_arg_info['fourth'] = lisp_arg_info['cadddr'];
function std_cadddr(a, env) {
  var u = a[0];

  if (u == T) {
    throw new Error('***** T is not a list');
  }

  return u.cdr.cdr.cdr.car;
};
builtins['cadddr'] = new builtin_function(std_cadddr, 1, false, [TYPE_PAIR | TYPE_BOOLEAN], FTYPE_EXPR);
builtins['fourth'] = builtins['cadddr'];
lisp_docs['lastpair'] = 'lastpair';
interpreted_builtins['lastpair'] = '(de lastpair (l)\n(if (or (atom l) (atom (cdr l)))\n  l\n  (lastpair (cdr l))))';
lisp_docs['cdadar'] = '(cdadar u) is equivalent to (cdr (car (cdr (car u))))';
lisp_arg_info['cdadar'] = '[pair | boolean]';
function std_cdadar(a, env) {
  var u = a[0];

  if (u == T) {
    throw new Error('***** T is not a list');
  }

  return u.car.cdr.car.cdr;
};
builtins['cdadar'] = new builtin_function(std_cdadar, 1, false, [TYPE_PAIR | TYPE_BOOLEAN], FTYPE_EXPR);
lisp_docs['cddr'] = '(cddr u) is equivalent to (cdr (cdr u))';
lisp_arg_info['cddr'] = '[pair | boolean]';
function std_cddr(a, env) {
  var u = a[0];

  if (u == T) {
    throw new Error('***** T is not a list');
  }

  return u.cdr.cdr;
};
builtins['cddr'] = new builtin_function(std_cddr, 1, false, [TYPE_PAIR | TYPE_BOOLEAN], FTYPE_EXPR);
lisp_docs['cdaadr'] = '(cdaadr u) is equivalent to (cdr (car (car (cdr u))))';
lisp_arg_info['cdaadr'] = '[pair | boolean]';
function std_cdaadr(a, env) {
  var u = a[0];

  if (u == T) {
    throw new Error('***** T is not a list');
  }

  return u.cdr.car.car.cdr;
};
builtins['cdaadr'] = new builtin_function(std_cdaadr, 1, false, [TYPE_PAIR | TYPE_BOOLEAN], FTYPE_EXPR);
lisp_docs['third'] = 'synonymous with caddr';
lisp_docs['caddr'] = '(caddr u) is equivalent to (car (cdr (cdr u)))';
lisp_arg_info['caddr'] = '[pair | boolean]';
lisp_arg_info['third'] = lisp_arg_info['caddr'];
function std_caddr(a, env) {
  var u = a[0];

  if (u == T) {
    throw new Error('***** T is not a list');
  }

  return u.cdr.cdr.car;
};
builtins['caddr'] = new builtin_function(std_caddr, 1, false, [TYPE_PAIR | TYPE_BOOLEAN], FTYPE_EXPR);
builtins['third'] = builtins['caddr'];
lisp_docs['lastcar'] = 'lastcar';
interpreted_builtins['lastcar'] = '(de lastcar (l)\n(if (atom l) l (car (lastpair l))))';
lisp_docs['nth'] = 'returns the zero indexed I\'th element of L';
interpreted_builtins['nth'] = '(de nth (i l)\n(cond ((eqn i 0) (car l))\n      (t (nth (sub1 i) (cdr l)))))';
lisp_docs['rplacd'] = 'explaining what rplacd is / how it is used!';
lisp_arg_info['rplacd'] = '[pair], [[any]]';
function std_rplacd(a, env) {
  var u = a[0];
  var v = a[1];

  u.cdr = v;
  return u;
};
builtins['rplacd'] = new builtin_function(std_rplacd, 2, true, [TYPE_PAIR, CLASS_ANY], FTYPE_EXPR);
lisp_docs['caadr'] = '(caadr u) is equivalent to (car (car (cdr u)))';
lisp_arg_info['caadr'] = '[pair | boolean]';
function std_caadr(a, env) {
  var u = a[0];

  if (u == T) {
    throw new Error('***** T is not a list');
  }

  return u.cdr.car.car;
};
builtins['caadr'] = new builtin_function(std_caadr, 1, false, [TYPE_PAIR | TYPE_BOOLEAN], FTYPE_EXPR);
lisp_docs['cddddr'] = '(cddddr u) is equivalent to (cdr (cdr (cdr (cdr u))))';
lisp_arg_info['cddddr'] = '[pair | boolean]';
function std_cddddr(a, env) {
  var u = a[0];

  if (u == T) {
    throw new Error('***** T is not a list');
  }

  return u.cdr.cdr.cdr.cdr;
};
builtins['cddddr'] = new builtin_function(std_cddddr, 1, false, [TYPE_PAIR | TYPE_BOOLEAN], FTYPE_EXPR);
lisp_docs['cdar'] = '(cdar u) is equivalent to (cdr (car u))';
lisp_arg_info['cdar'] = '[pair | boolean]';
function std_cdar(a, env) {
  var u = a[0];

  if (u == T) {
    throw new Error('***** T is not a list');
  }

  return u.car.cdr;
};
builtins['cdar'] = new builtin_function(std_cdar, 1, false, [TYPE_PAIR | TYPE_BOOLEAN], FTYPE_EXPR);
lisp_docs['cadadr'] = '(cadadr u) is equivalent to (car (cdr (car (cdr u))))';
lisp_arg_info['cadadr'] = '[pair | boolean]';
function std_cadadr(a, env) {
  var u = a[0];

  if (u == T) {
    throw new Error('***** T is not a list');
  }

  return u.cdr.car.cdr.car;
};
builtins['cadadr'] = new builtin_function(std_cadadr, 1, false, [TYPE_PAIR | TYPE_BOOLEAN], FTYPE_EXPR);
lisp_docs['cdaddr'] = '(cdaddr u) is equivalent to (cdr (car (cdr (cdr u))))';
lisp_arg_info['cdaddr'] = '[pair | boolean]';
function std_cdaddr(a, env) {
  var u = a[0];

  if (u == T) {
    throw new Error('***** T is not a list');
  }

  return u.cdr.cdr.car.cdr;
};
builtins['cdaddr'] = new builtin_function(std_cdaddr, 1, false, [TYPE_PAIR | TYPE_BOOLEAN], FTYPE_EXPR);
lisp_docs['rplaca'] = 'explaining what rplaca is / how it is used!';
lisp_arg_info['rplaca'] = '[pair], [[any]]';
function std_rplaca(a, env) {
  var u = a[0];
  var v = a[1];

  u.car = v;
  return u;
};
builtins['rplaca'] = new builtin_function(std_rplaca, 2, true, [TYPE_PAIR, CLASS_ANY], FTYPE_EXPR);
lisp_docs['first'] = 'synonymous with car';
lisp_docs['car'] = 'explaining what car is / how it is used!';
lisp_arg_info['car'] = '[pair | boolean]';
lisp_arg_info['first'] = lisp_arg_info['car'];
function std_car(a, env) {
  var u = a[0];

  if (u == T) {
    throw new Error('***** T is not a list');
  }

  return u.car;
};
builtins['car'] = new builtin_function(std_car, 1, false, [TYPE_PAIR | TYPE_BOOLEAN], FTYPE_EXPR);
builtins['first'] = builtins['car'];
lisp_docs['list'] = 'explaining what list is / how it is used!';
lisp_arg_info['list'] = '[[any]]';
function std_list(a, env) {
  var u = a[0];

  var head = new lisp_pair(u[0].evaluate(env), NIL);
  var ptr = head;

  for (var i = 1; i < u.length; i++) {
    ptr.cdr = new lisp_pair(u[i].evaluate(env), NIL);
    ptr = ptr.cdr;
  }

  return head;
};
builtins['list'] = new builtin_function(std_list, 0, true, [CLASS_ANY], FTYPE_FEXPR);
lisp_docs['cdaar'] = '(cdaar u) is equivalent to (cdr (car (car u)))';
lisp_arg_info['cdaar'] = '[pair | boolean]';
function std_cdaar(a, env) {
  var u = a[0];

  if (u == T) {
    throw new Error('***** T is not a list');
  }

  return u.car.car.cdr;
};
builtins['cdaar'] = new builtin_function(std_cdaar, 1, false, [TYPE_PAIR | TYPE_BOOLEAN], FTYPE_EXPR);
lisp_docs['caaddr'] = '(caaddr u) is equivalent to (car (car (cdr (cdr u))))';
lisp_arg_info['caaddr'] = '[pair | boolean]';
function std_caaddr(a, env) {
  var u = a[0];

  if (u == T) {
    throw new Error('***** T is not a list');
  }

  return u.cdr.cdr.car.car;
};
builtins['caaddr'] = new builtin_function(std_caaddr, 1, false, [TYPE_PAIR | TYPE_BOOLEAN], FTYPE_EXPR);
lisp_docs['cddaar'] = '(cddaar u) is equivalent to (cdr (cdr (car (car u))))';
lisp_arg_info['cddaar'] = '[pair | boolean]';
function std_cddaar(a, env) {
  var u = a[0];

  if (u == T) {
    throw new Error('***** T is not a list');
  }

  return u.car.car.cdr.cdr;
};
builtins['cddaar'] = new builtin_function(std_cddaar, 1, false, [TYPE_PAIR | TYPE_BOOLEAN], FTYPE_EXPR);
lisp_docs['and'] = 'evaluates each U until it encounters either NIL or the end of the  list, whereupon this value is returned';
lisp_arg_info['and'] = '[U [any]]';
function std_and(a, env) {
  var u = a[0];

  var last = NIL;
  for (var i = 0; i < u.length; i++) {
    last = u[i].evaluate(env);
    if (last == NIL) {
      return NIL;
    }
  }

  return last;
};
builtins['and'] = new builtin_function(std_and, 0, true, [CLASS_ANY], FTYPE_FEXPR);
lisp_docs['unless'] = 'explaining what unless is / how it is used!';
interpreted_builtins['unless'] = '(dm unless (u)\n(let ((test (second u))\n       (e (cddr u)))\n  `(if ,test nil ,@e)))';
lisp_docs['null'] = 'synonymous with not';
lisp_docs['not'] = 'Returns T if U is NIL, else return NIL.';
lisp_arg_info['not'] = 'U [any]';
lisp_arg_info['null'] = lisp_arg_info['not'];
function std_not(a, env) {
  var u = a[0];

  return (u == NIL) ? T : NIL;
};
builtins['not'] = new builtin_function(std_not, 1, false, [CLASS_ANY], FTYPE_EXPR);
builtins['null'] = builtins['not'];
lisp_docs['cond'] = 'Takes U in the form of ((ANTECEDENT1 CONSEQUENT1)(ANTECEDENT2 CONSEQUENT2)...)  and evaluates each antecedent until a non-NIL value is encountered, at  which point the related consequent is evaluated and returned.  If no non-NIL  antecedent is encountered, NIL is returned.';
lisp_arg_info['cond'] = '[U [pair]]';
function std_cond(a, env) {
  var u = a[0];

  for (var i = 0; i < u.length; i++) {
    var antecedent = u[i].car;
    var consequent = u[i].cdr.car;

    if (antecedent.evaluate(env) != NIL) {
      return consequent.evaluate(env);
    }
  }

  return NIL;
};
builtins['cond'] = new builtin_function(std_cond, 0, true, [TYPE_PAIR], FTYPE_FEXPR);
lisp_docs['when'] = 'explaining what when is / how it is used!';
interpreted_builtins['when'] = '(dm when (u)\n(let ((test (second u))\n       (e (cddr u)))\n  `(if ,test (progn ,@e))))';
lisp_docs['or'] = 'Returns the first of U which evaluates to non-NIL or NIL if none do.';
lisp_arg_info['or'] = '[U [any]]';
function std_or(a, env) {
  var u = a[0];

  var last = null;
  for (var i = 0; i < u.length; i++) {
    last = u[i].evaluate(env);
    if (last != NIL) {
      return last;
    }
  }
  return NIL;
};
builtins['or'] = new builtin_function(std_or, 0, true, [CLASS_ANY], FTYPE_FEXPR);
lisp_docs['if'] = 'then-form is evaluated if test-form is non-NIL otherwise the members of then-form are evaluated.';
interpreted_builtins['if'] = '(dm if (u)\n(let ((test-form (second u))\n       (then-form (third u))\n       (else-form (cdddr u)))\n  `(cond (,test-form ,then-form) (t (progn ,@else-form)))))';
lisp_docs['globalp'] = 'explaining what globalp is / how it is used!';
lisp_arg_info['globalp'] = '[any]';
function std_globalp(a, env) {
  var u = a[0];

  throw new Error('GLOBALP not implemented (yet)');
};
builtins['globalp'] = new builtin_function(std_globalp, 1, false, [CLASS_ANY], FTYPE_EXPR);
lisp_docs['set'] = 'explaining what set is / how it is used!';
lisp_arg_info['set'] = '[id], [any]';
function std_set(a, env) {
  var expr = a[0];
  var value = a[1];

  env.variables.set(expr.value, value);

  return value;
};
builtins['set'] = new builtin_function(std_set, 2, false, [TYPE_ID, CLASS_ANY], FTYPE_EXPR);
lisp_docs['unfluid'] = 'explaining what unfluid is / how it is used!';
lisp_arg_info['unfluid'] = '[pair]';
function std_unfluid(a, env) {
  var idlist = a[0];

  throw new Error('UNFLUID not implemented (yet)');
};
builtins['unfluid'] = new builtin_function(std_unfluid, 1, false, [TYPE_PAIR], FTYPE_EXPR);
lisp_docs['setq'] = 'explaining what setq is / how it is used!';
lisp_arg_info['setq'] = '[id], [any]';
function std_setq(a, env) {
  var variable = a[0];
  var value = a[1];

  value = value.evaluate(env);
  env.variables.set(variable.value, value);

  return value;
};
builtins['setq'] = new builtin_function(std_setq, 2, false, [TYPE_ID, CLASS_ANY], FTYPE_FEXPR);
lisp_docs['global'] = 'explaining what global is / how it is used!';
lisp_arg_info['global'] = '[pair]';
function std_global(a, env) {
  var idlist = a[0];

  throw new Error('GLOBAL not implemented (yet)');
};
builtins['global'] = new builtin_function(std_global, 1, false, [TYPE_PAIR], FTYPE_EXPR);
lisp_docs['fluid'] = 'explaining what fluid is / how it is used!';
lisp_arg_info['fluid'] = '[pair]';
function std_fluid(a, env) {
  var idlist = a[0];

  throw new Error('FLUID not implemented (yet)');
};
builtins['fluid'] = new builtin_function(std_fluid, 1, false, [TYPE_PAIR], FTYPE_EXPR);
lisp_docs['fluidp'] = 'explaining what fluidp is / how it is used!';
lisp_arg_info['fluidp'] = '[any]';
function std_fluidp(a, env) {
  var u = a[0];

  throw new Error('FLUIDP not implemented (yet)');
};
builtins['fluidp'] = new builtin_function(std_fluidp, 1, false, [CLASS_ANY], FTYPE_EXPR);
lisp_docs['channelreadline'] = 'explaining what channelreadline is / how it is used!';
lisp_arg_info['channelreadline'] = '[channel]';
std_channelreadline = function(a, env) {
  var channel;
  channel = a[0];
  return new lisp_string(channel.readline());
};
builtins['channelreadline'] = new builtin_function(std_channelreadline, 1, false, [TYPE_CHANNEL], FTYPE_EXPR);
lisp_docs['channelreadch'] = 'explaining what channelreadch is / how it is used!';
lisp_arg_info['channelreadch'] = '[channel]';
function std_channelreadch(a, env) {
  var channel = a[0];

  return new lisp_id(channel.readch(), env.oblist);
};
builtins['channelreadch'] = new builtin_function(std_channelreadch, 1, false, [TYPE_CHANNEL], FTYPE_EXPR);
lisp_docs['to-string'] = 'synonymous with prin1-to-string';
lisp_docs['prin1-to-string'] = 'explaining what prin1-to-string is / how it is used!';
lisp_arg_info['prin1-to-string'] = '[any]';
lisp_arg_info['to-string'] = lisp_arg_info['prin1-to-string'];
std_prin1_to_string = function(a, env) {
  var u;
  u = a[0];
  return new lisp_string(u.prin1());
};
builtins['prin1-to-string'] = new builtin_function(std_prin1_to_string, 1, false, [CLASS_ANY], FTYPE_EXPR);
builtins['to-string'] = builtins['prin1-to-string'];
lisp_docs['read'] = 'explaining what read is / how it is used!';
interpreted_builtins['read'] = '(de read nil\n(channelread IN*))';
lisp_docs['prin2-to-string'] = 'explaining what prin2-to-string is / how it is used!';
lisp_arg_info['prin2-to-string'] = '[any]';
std_prin2_to_string = function(a, env) {
  var u;
  u = a[0];
  return new lisp_string(u.prin2());
};
builtins['prin2-to-string'] = new builtin_function(std_prin2_to_string, 1, false, [CLASS_ANY], FTYPE_EXPR);
lisp_docs['close'] = 'explaining what close is / how it is used!';
lisp_arg_info['close'] = '[channel]';
function std_close(a, env) {
  var channel = a[0];

  if (channel.mode & CHANNEL_OUTPUT) {
    env.files[channel.name] = channel.flush();
  }

  return NIL;
};
builtins['close'] = new builtin_function(std_close, 1, false, [TYPE_CHANNEL], FTYPE_EXPR);
lisp_docs['open'] = 'explaining what open is / how it is used!';
lisp_arg_info['open'] = '[string], [id]';
function std_open(a, env) {
  var file = a[0].value;
  var how = a[1];
  
  var mode = CHANNEL_OUTPUT;

  if (how.value == 'output') {
    env.files[file] = '';
  }

  if (how.value == 'output') {
    mode = CHANNEL_OUTPUT;
  } else if (how.value == 'input') {
    mode = CHANNEL_INPUT;
  }

  if (env.files[file] != undefined) {
    return channel = new lisp_channel(env.files[file].slice(0), mode, file);
  } else {
    throw new lisp_error(ERROR_INTERNAL, T, "file not found")
  }
};
builtins['open'] = new builtin_function(std_open, 2, false, [TYPE_STRING, TYPE_ID], FTYPE_EXPR);
lisp_docs['rds'] = 'explaining what rds is / how it is used!';
lisp_arg_info['rds'] = '[channel | boolean]';
std_rds = function(a, env) {
  var channel, now;
  channel = a[0];
  if (channel === T) {
    throw new lisp_error("T not NIL for rds");
  }
  now = env.variables.get('IN*');
  if (channel === NIL) {
    env.variables.set('IN*', env.variables.get('STDIN*'));
  } else {
    env.variables.set('IN*', channel);
  }
  return now;
};
builtins['rds'] = new builtin_function(std_rds, 1, false, [TYPE_CHANNEL | TYPE_BOOLEAN], FTYPE_EXPR);
lisp_docs['terpri'] = 'explaining what terpri is / how it is used!';
interpreted_builtins['terpri'] = '(de terpri nil\n(channelterpri OUT*))';
lisp_docs['channelread'] = 'explaining what channelread is / how it is used!';
lisp_arg_info['channelread'] = '[channel]';
function std_channelread(a, env) {
  var channel = a[0];

  return channel.read(env);
};
builtins['channelread'] = new builtin_function(std_channelread, 1, false, [TYPE_CHANNEL], FTYPE_EXPR);
lisp_docs['channelprint'] = 'explaining what channelprint is / how it is used!';
interpreted_builtins['channelprint'] = '(de channelprint (c u)\n(prog (v)\n  (setq v (channelprin1 c u))\n  (channelterpri c)\n  (return v)))';
lisp_docs['rdf'] = 'explaining what rdf is / how it is used!';
lisp_arg_info['rdf'] = '[string]';
function std_rdf(a, env) {
  var channel = new lisp_channel(env.files[a[0].value]);

  while (true) {
    var expr = channel.read(env);
    if (expr == EOF) {
      break;
    }
    expr.evaluate(env);
  }
  return NIL;
};
builtins['rdf'] = new builtin_function(std_rdf, 1, false, [TYPE_STRING], FTYPE_EXPR);
lisp_docs['channelprinc'] = 'synonymous with channelprin2';
lisp_docs['channelprin2'] = 'explaining what channelprin2 is / how it is used!';
lisp_arg_info['channelprin2'] = '[channel], [any]';
lisp_arg_info['channelprinc'] = lisp_arg_info['channelprin2'];
function std_channelprin2(a, env) {
  var channel = a[0];
  var u = a[1];

  channel.write(u.prin2());

  return u;
};
builtins['channelprin2'] = new builtin_function(std_channelprin2, 2, false, [TYPE_CHANNEL, CLASS_ANY], FTYPE_EXPR);
builtins['channelprinc'] = builtins['channelprin2'];
lisp_docs['wrs'] = 'explaining what wrs is / how it is used!';
lisp_arg_info['wrs'] = '[channel | boolean]';
std_wrs = function(a, env) {
  var channel, now;
  channel = a[0];
  if (channel === T) {
    throw new lisp_error("T not NIL for wrs");
  }
  now = env.variables.get('OUT*');
  if (channel === NIL) {
    env.variables.set('OUT*', env.variables.get('STDOUT*'));
  } else {
    env.variables.set('OUT*', channel);
  }
  return now;
};
builtins['wrs'] = new builtin_function(std_wrs, 1, false, [TYPE_CHANNEL | TYPE_BOOLEAN], FTYPE_EXPR);
lisp_docs['channelprin1'] = 'explaining what channelprin1 is / how it is used!';
lisp_arg_info['channelprin1'] = '[channel], [any]';
function std_channelprin1(a, env) {
  var channel = a[0];
  var u = a[1];

  channel.write(u.prin1());

  return u;
};
builtins['channelprin1'] = new builtin_function(std_channelprin1, 2, false, [TYPE_CHANNEL, CLASS_ANY], FTYPE_EXPR);
lisp_docs['print'] = 'explaining what print is / how it is used!';
interpreted_builtins['print'] = '(de print (u)\n(channelprint OUT* u))';
lisp_docs['readch'] = 'explaining what readch is / how it is used!';
interpreted_builtins['readch'] = '(de readch nil\n(channelreadch IN*))';
lisp_docs['channelterpri'] = 'explaining what channelterpri is / how it is used!';
lisp_arg_info['channelterpri'] = '[channel]';
function std_channelterpri(a, env) {
  var channel = a[0];

  channel.write('\n');

  return NIL;
};
builtins['channelterpri'] = new builtin_function(std_channelterpri, 1, false, [TYPE_CHANNEL], FTYPE_EXPR);
lisp_docs['prin1'] = 'explaining what prin1 is / how it is used!';
interpreted_builtins['prin1'] = '(de prin1 (u)\n(channelprin1 OUT* u))';
lisp_docs['princ'] = 'synonymous with prin2';
lisp_docs['prin2'] = 'explaining what prin2 is / how it is used!';
interpreted_builtins['prin2'] = '(de prin2 (u)\n(channelprin2 OUT* u))';
interpreted_builtins['princ'] = '(dm princ (u) `(prin2 ,@(rest u)))';
lisp_docs['remprop'] = 'explaining what remprop is / how it is used!';
lisp_arg_info['remprop'] = '[any], [any]';
function std_remprop(a, env) {
  var u = a[0];
  var ind = a[1];

  if (u.proplist[ind.value] != undefined) {
    var val = u.proplist[ind.value];
    delete u.proplist[ind.value];
    return val;
  } else {
    return NIL;
  }
};
builtins['remprop'] = new builtin_function(std_remprop, 2, false, [CLASS_ANY, CLASS_ANY], FTYPE_EXPR);
lisp_docs['flag'] = 'explaining what flag is / how it is used!';
lisp_arg_info['flag'] = '[pair], [id]';
function std_flag(a, env) {
  var u = a[0];
  var v = a[1];

  for (var p = u; p != NIL; p = p.cdr) {
    if (type_check(p.car.type, TYPE_ID)) {
      p.car.flags[v.value] = true;
    } else {
      // raise an error?
    }
  }

  return NIL;
};
builtins['flag'] = new builtin_function(std_flag, 2, false, [TYPE_PAIR, TYPE_ID], FTYPE_EXPR);
lisp_docs['remflag'] = 'explaining what remflag is / how it is used!';
lisp_arg_info['remflag'] = '[pair], [id]';
function std_remflag(a, env) {
  var u = a[0];
  var v = a[1];

  for (var p = u; p != NIL; p = p.cdr) {
    if (type_check(p.car.type, TYPE_ID)) {
      delete p.car.flags[v.value];
    } else {
      // raise an error?
    }
  }

  return NIL;
};
builtins['remflag'] = new builtin_function(std_remflag, 2, false, [TYPE_PAIR, TYPE_ID], FTYPE_EXPR);
lisp_docs['get'] = 'explaining what get is / how it is used!';
lisp_arg_info['get'] = '[any], [any]';
function std_get(a, env) {
  var u = a[0];
  var ind = a[1];

  if (u.proplist[ind.value] != undefined) {
    return u.proplist[ind.value];
  } else {
    return NIL;
  }
};
builtins['get'] = new builtin_function(std_get, 2, false, [CLASS_ANY, CLASS_ANY], FTYPE_EXPR);
lisp_docs['put'] = 'explaining what put is / how it is used!';
lisp_arg_info['put'] = '[id], [id], [any]';
function std_put(a, env) {
  var u = a[0];
  var ind = a[1];
  var prop = a[2];

  u.proplist[ind.value] = prop;

  return prop;
};
builtins['put'] = new builtin_function(std_put, 3, false, [TYPE_ID, TYPE_ID, CLASS_ANY], FTYPE_EXPR);
lisp_docs['flagp'] = 'explaining what flagp is / how it is used!';
lisp_arg_info['flagp'] = '[any], [any]';
function std_flagp(a, env) {
  var u = a[0];
  var v = a[1];

  if (type_check(u.type, TYPE_ID) && type_check(v.type, TYPE_ID)) {
    if (u.flags[v.value] != undefined) {
      return T;
    }
  }

  return NIL;
};
builtins['flagp'] = new builtin_function(std_flagp, 2, false, [CLASS_ANY, CLASS_ANY], FTYPE_EXPR);
lisp_docs['vector-empty?'] = 'explaining what vector-empty? is / how it is used!';
lisp_arg_info['vector-empty?'] = '[vector]';
std_vector_emptyqmark = function(a, env) {
  var v;
  v = a[0].value;
  if (v.length === 0) {
    return T;
  } else {
    return NIL;
  }
};
builtins['vector-empty?'] = new builtin_function(std_vector_emptyqmark, 1, false, [TYPE_VECTOR], FTYPE_EXPR);
lisp_docs['fixp'] = 'explaining what fixp is / how it is used!';
lisp_arg_info['fixp'] = '[any]';
function std_fixp(a, env) {
  var u = a[0];

  return type_check(u.type, TYPE_INTEGER) ? T : NIL;
};
builtins['fixp'] = new builtin_function(std_fixp, 1, false, [CLASS_ANY], FTYPE_EXPR);
lisp_docs['onep'] = 'explaining what onep is / how it is used!';
lisp_arg_info['onep'] = '[any]';
function std_onep(a, env) {
  var u = a[0];

  if (type_check(u.type, CLASS_NUMBER)) {
    return (u.value == 1) ? T : NIL;
  } else {
    return NIL;
  }
};
builtins['onep'] = new builtin_function(std_onep, 1, false, [CLASS_ANY], FTYPE_EXPR);
lisp_docs['string-startswith'] = 'string-startswith';
interpreted_builtins['string-startswith'] = '(de string-startswith (s e)\n(string= e\n         (substring s 0 (string-length e))))';
lisp_docs['numberp'] = 'explaining what numberp is / how it is used!';
lisp_arg_info['numberp'] = '[any]';
function std_numberp(a, env) {
  var u = a[0];

  return type_check(u.type, CLASS_NUMBER) ? T : NIL;
};
builtins['numberp'] = new builtin_function(std_numberp, 1, false, [CLASS_ANY], FTYPE_EXPR);
lisp_docs['atom'] = 'explaining what atom is / how it is used!';
lisp_arg_info['atom'] = '[any]';
function std_atom(a, env) {
  var u = a[0];

  return type_check(u.type, CLASS_ATOM) ? T : NIL;
};
builtins['atom'] = new builtin_function(std_atom, 1, false, [CLASS_ANY], FTYPE_EXPR);
lisp_docs['string-empty?'] = 'explaining what string-empty? is / how it is used!';
lisp_arg_info['string-empty?'] = '[string]';
std_string_emptyqmark = function(a, env) {
  var str;
  str = a[0].value;
  if (str === '') {
    return T;
  } else {
    return NIL;
  }
};
builtins['string-empty?'] = new builtin_function(std_string_emptyqmark, 1, false, [TYPE_STRING], FTYPE_EXPR);
lisp_docs['floatp'] = 'explaining what floatp is / how it is used!';
lisp_arg_info['floatp'] = '[any]';
function std_floatp(a, env) {
  var u = a[0];

  return type_check(u.type, TYPE_FLOATING) ? T : NIL;
};
builtins['floatp'] = new builtin_function(std_floatp, 1, false, [CLASS_ANY], FTYPE_EXPR);
lisp_docs['constantp'] = 'explaining what constantp is / how it is used!';
lisp_arg_info['constantp'] = '[any]';
function std_constantp(a, env) {
  var u = a[0];

  return type_check(u.type, CLASS_CONSTANT) ? T : NIL;
};
builtins['constantp'] = new builtin_function(std_constantp, 1, false, [CLASS_ANY], FTYPE_EXPR);
lisp_docs['minusp'] = 'explaining what minusp is / how it is used!';
lisp_arg_info['minusp'] = '[any]';
function std_minusp(a, env) {
  var u = a[0];

  if (type_check(u.type, CLASS_NUMBER)) {
    return (u.value < 0) ? T : NIL;
  } else {
    return NIL;
  }
};
builtins['minusp'] = new builtin_function(std_minusp, 1, false, [CLASS_ANY], FTYPE_EXPR);
lisp_docs['codep'] = 'explaining what codep is / how it is used!';
lisp_arg_info['codep'] = '[any]';
function std_codep(a, env) {
  var u = a[0];

  return type_check(u.type, TYPE_FUNCTION) ? T : NIL;
};
builtins['codep'] = new builtin_function(std_codep, 1, false, [CLASS_ANY], FTYPE_EXPR);
lisp_docs['pairp'] = 'explaining what pairp is / how it is used!';
lisp_arg_info['pairp'] = '[any]';
function std_pairp(a, env) {
  var u = a[0];

  return type_check(u.type, TYPE_PAIR) ? T : NIL;
};
builtins['pairp'] = new builtin_function(std_pairp, 1, false, [CLASS_ANY], FTYPE_EXPR);
lisp_docs['string-endswith'] = 'string-endswith';
interpreted_builtins['string-endswith'] = '(de string-endswith (s e)\n(let ((slen (string-length s))\n      (elen (string-length e)))\n  (string= e\n           (substring s (- slen elen) slen)))))';
lisp_docs['idp'] = 'explaining what idp is / how it is used!';
lisp_arg_info['idp'] = '[any]';
function std_idp(a, env) {
  var u = a[0];

  return type_check(u.type, TYPE_ID) ? T : NIL;
};
builtins['idp'] = new builtin_function(std_idp, 1, false, [CLASS_ANY], FTYPE_EXPR);
lisp_docs['zerop'] = 'explaining what zerop is / how it is used!';
lisp_arg_info['zerop'] = '[any]';
function std_zerop(a, env) {
  var u = a[0];

  if (type_check(u.type, CLASS_NUMBER)) {
    return (u.value == 0) ? T : NIL;
  } else {
    return NIL;
  }
};
builtins['zerop'] = new builtin_function(std_zerop, 1, false, [CLASS_ANY], FTYPE_EXPR);
lisp_docs['stringp'] = 'explaining what stringp is / how it is used!';
lisp_arg_info['stringp'] = '[any]';
function std_stringp(a, env) {
  var u = a[0];

  return type_check(u.type, TYPE_STRING) ? T : NIL;
};
builtins['stringp'] = new builtin_function(std_stringp, 1, false, [CLASS_ANY], FTYPE_EXPR);
lisp_docs['function'] = 'explaining what function is / how it is used!';
lisp_arg_info['function'] = '[function | id]';
function std_function(a, env) {
  var u = a[0];

  if (u.type == TYPE_ID) {
    return env.functions.get(u.value);
  } else {
    return u;
  }
};
builtins['function'] = new builtin_function(std_function, 1, false, [TYPE_FUNCTION | TYPE_ID], FTYPE_FEXPR);
lisp_docs['unquote'] = 'explaining what unquote is / how it is used!';
lisp_arg_info['unquote'] = 'FORM [any]';
std_unquote = function(a, env) {
  throw new Error('unquote illegal outside of backquote');
};
builtins['unquote'] = new builtin_function(std_unquote, 1, false, [CLASS_ANY], FTYPE_FEXPR);
lisp_docs['evlis'] = 'explaining what evlis is / how it is used!';
lisp_arg_info['evlis'] = '[any]';
function std_evlis(a, env) {
  var u = a[0];

  var head = new lisp_pair(u.car.evaluate(env), NIL);
  var ptr = head;

  for (var p = u.cdr; p != NIL; p = p.cdr) {
    ptr.cdr = new lisp_pair(p.car.evaluate(env), NIL);
    ptr = ptr.cdr;
  }

  return head;
};
builtins['evlis'] = new builtin_function(std_evlis, 1, false, [CLASS_ANY], FTYPE_EXPR);
lisp_docs['eval'] = 'explaining what eval is / how it is used!';
lisp_arg_info['eval'] = '[any]';
function std_eval(a, env) {
  var u = a[0];

  return u.evaluate(env);
};
builtins['eval'] = new builtin_function(std_eval, 1, false, [CLASS_ANY], FTYPE_EXPR);
lisp_docs['quote'] = 'explaining what quote is / how it is used!';
lisp_arg_info['quote'] = '[any]';
function std_quote(a, env) {
  var u = a[0];

  return u;
};
builtins['quote'] = new builtin_function(std_quote, 1, false, [CLASS_ANY], FTYPE_FEXPR);
lisp_docs['unquotel'] = 'explaining what unquotel is / how it is used!';
lisp_arg_info['unquotel'] = 'FORM [any]';
std_unquotel = function(a, env) {
  throw new Error('unquotel illegal outside of backquote');
};
builtins['unquotel'] = new builtin_function(std_unquotel, 1, false, [CLASS_ANY], FTYPE_FEXPR);
lisp_docs['backquote'] = 'explaining what backquote is / how it is used!';
lisp_arg_info['backquote'] = 'FORM [any]';
std_backquote = function(a, env) {
  var elm, form, out, val, _i, _len, _ref;
  form = a[0];
  if (form.type !== TYPE_PAIR) {
    return form;
  } else {
    out = [];
    _ref = list_to_array(form);
    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
      elm = _ref[_i];
      if (elm.type === TYPE_PAIR) {
        if (elm.car.type === TYPE_ID) {
          if (elm.car.value === 'unquote') {
            out.push(elm.cdr.car.evaluate(env));
            continue;
          } else if (elm.car.value === 'unquotel') {
            val = elm.cdr.car.evaluate(env);
            if (val.type !== TYPE_PAIR) {
              out.push('.');
              out.push(val);
            } else {
              out = out.concat(list_to_array(val));
            }
            continue;
          }
        }
      }
      out.push(std_backquote([elm], env));
    }
    return array_to_list(out);
  }
};
builtins['backquote'] = new builtin_function(std_backquote, 1, false, [CLASS_ANY], FTYPE_FEXPR);
lisp_docs['apply'] = 'explaining what apply is / how it is used!';
lisp_arg_info['apply'] = '[id | function], [pair]';
std_apply = function(a, env) {
  var args, e, fn;
  fn = a[0];
  args = a[1];
  return APPLYN(fn, array_to_list((function() {
    var _i, _len, _ref, _results;
    _ref = list_to_array(args);
    _results = [];
    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
      e = _ref[_i];
      _results.push(QUOTE(e, env));
    }
    return _results;
  })())).evaluate(env);
};
builtins['apply'] = new builtin_function(std_apply, 2, false, [TYPE_ID | TYPE_FUNCTION, TYPE_PAIR], FTYPE_EXPR);
lisp_docs['expand'] = 'explaining what expand is / how it is used!';
interpreted_builtins['expand'] = '(de expand (l fn)\n(cond\n  ((null (cdr l)) (car l))\n  (T (list fn (car l) (expand (cdr l) fn)))))';
lisp_docs['>='] = 'synonymous with geq';
lisp_docs['geq'] = 'returns T if U >= V otherwise returns NIL';
lisp_arg_info['geq'] = 'U [number], V [number]';
lisp_arg_info['>='] = lisp_arg_info['geq'];
std_geq = function(a, env) {
  var args, u, v;
  args = homogenize_args(a);
  u = args[0].value;
  v = args[1].value;
  if (args[0].type === TYPE_INTEGER) {
    if (u.compare(v) in [0, 1]) {
      return T;
    } else {
      return NIL;
    }
  } else {
    if (u >= v) {
      return T;
    } else {
      return NIL;
    }
  }
};
builtins['geq'] = new builtin_function(std_geq, 2, false, [CLASS_NUMBER, CLASS_NUMBER], FTYPE_EXPR);
builtins['>='] = builtins['geq'];
lisp_docs['string<>'] = 'string<>';
lisp_arg_info['string<>'] = 'S1 [string], S2 [string]';
std_stringltmarkgtmark = function(a, env) {
  var i, s1, s2, uplim;
  s1 = a[0].value;
  s2 = a[1].value;
  if (s1 !== s2) {
    uplim = Math.min(s1.length, s2.length);
    for (i = 0; 0 <= uplim ? i < uplim : i > uplim; 0 <= uplim ? i++ : i--) {
      if (s1.charAt(i) !== s2.charAt(i)) {
        return new lisp_integer(i);
      }
    }
    return new lisp_integer(uplim);
  } else {
    return NIL;
  }
};
builtins['string<>'] = new builtin_function(std_stringltmarkgtmark, 2, false, [TYPE_STRING, TYPE_STRING], FTYPE_EXPR);
lisp_docs['string-lessp'] = 'string-lessp';
lisp_arg_info['string-lessp'] = 'S1 [string], S2 [string]';
std_string_lessp = function(a, env) {
  var i, s1, s2, uplim;
  s1 = a[0].value.toLowerCase();
  s2 = a[1].value.toLowerCase();
  if (s1 < s2) {
    uplim = Math.min(s1.length, s2.length);
    for (i = 0; 0 <= uplim ? i < uplim : i > uplim; 0 <= uplim ? i++ : i--) {
      if (s1.charAt(i) !== s2.charAt(i)) {
        return new lisp_integer(i);
      }
    }
    return new lisp_integer(uplim);
  } else {
    return NIL;
  }
};
builtins['string-lessp'] = new builtin_function(std_string_lessp, 2, false, [TYPE_STRING, TYPE_STRING], FTYPE_EXPR);
lisp_docs['equal'] = 'explaining what equal is / how it is used!';
lisp_arg_info['equal'] = '[any], [any]';
function std_equal(a, env) {
  var u = a[0];
  var v = a[1];

  if (std_eqn([u, v], env) == T) {
    return T;
  }

  switch (u.type) {
  case TYPE_STRING:
    return (u.value == v.value) ? T : NIL;
  case TYPE_VECTOR:
    if (u.value.length != v.value.length) {
      return NIL;
    } else {
      for (var i = 0; i < u.value.length; i++) {
        if (std_equal([u.value[i], v.value[i]], env) == NIL) {
          return NIL;
        }
      }
      return T;
    }
  case TYPE_PAIR:
    if (v.type == TYPE_PAIR) {
      if (std_equal([u.car, v.car], env) == NIL) {
        return NIL;
      } else {
        return std_equal([u.cdr, v.cdr], env);
      }
    } else {
      return NIL;
    }
  }

  return NIL;
};
builtins['equal'] = new builtin_function(std_equal, 2, false, [CLASS_ANY, CLASS_ANY], FTYPE_EXPR);
lisp_docs['string>='] = 'string>=';
lisp_arg_info['string>='] = 'S1 [string], S2 [string]';
std_stringgtmarkeqmark = function(a, env) {
  var i, s1, s2, uplim;
  s1 = a[0].value;
  s2 = a[1].value;
  if (s1 >= s2) {
    uplim = Math.min(s1.length, s2.length);
    for (i = 0; 0 <= uplim ? i < uplim : i > uplim; 0 <= uplim ? i++ : i--) {
      if (s1.charAt(i) !== s2.charAt(i)) {
        return new lisp_integer(i);
      }
    }
    return new lisp_integer(uplim);
  } else {
    return NIL;
  }
};
builtins['string>='] = new builtin_function(std_stringgtmarkeqmark, 2, false, [TYPE_STRING, TYPE_STRING], FTYPE_EXPR);
lisp_docs['<='] = 'synonymous with leq';
lisp_docs['leq'] = 'returns T if U <= V otherwise returns NIL';
lisp_arg_info['leq'] = 'U [number], V [number]';
lisp_arg_info['<='] = lisp_arg_info['leq'];
std_leq = function(a, env) {
  var args, comp, u, v;
  args = homogenize_args(a);
  u = args[0].value;
  v = args[1].value;
  if (args[0].type === TYPE_INTEGER) {
    comp = u.compare(v);
    if (comp === 0 || comp === -1) {
      return T;
    } else {
      return NIL;
    }
  } else {
    if (u <= v) {
      return T;
    } else {
      return NIL;
    }
  }
};
builtins['leq'] = new builtin_function(std_leq, 2, false, [CLASS_NUMBER, CLASS_NUMBER], FTYPE_EXPR);
builtins['<='] = builtins['leq'];
lisp_docs['eq'] = 'explaining what eq is / how it is used!';
lisp_arg_info['eq'] = '[any], [any]';
function std_eq(a, env) {
  var u = a[0];
  var v = a[1];

  return (u == v) ? T : NIL;
};
builtins['eq'] = new builtin_function(std_eq, 2, false, [CLASS_ANY, CLASS_ANY], FTYPE_EXPR);
lisp_docs['/='] = 'synonymous with neqn';
lisp_docs['~='] = 'synonymous with neqn';
lisp_docs['neqn'] = 'explaining what neqn is / how it is used!';
interpreted_builtins['neqn'] = '(de neqn (u v)\n(not (eqn u v)))';
interpreted_builtins['/='] = '(dm /= (u) `(neqn ,@(rest u)))';
interpreted_builtins['~='] = '(dm ~= (u) `(neqn ,@(rest u)))';
lisp_docs['string-not-greaterp'] = 'string-not-greaterp';
lisp_arg_info['string-not-greaterp'] = 'S1 [string], S2 [string]';
std_string_not_greaterp = function(a, env) {
  var i, s1, s2, uplim;
  s1 = a[0].value.toLowerCase();
  s2 = a[1].value.toLowerCase();
  if (s1 <= s2) {
    uplim = Math.min(s1.length, s2.length);
    for (i = 0; 0 <= uplim ? i < uplim : i > uplim; 0 <= uplim ? i++ : i--) {
      if (s1.charAt(i) !== s2.charAt(i)) {
        return new lisp_integer(i);
      }
    }
    return new lisp_integer(uplim);
  } else {
    return NIL;
  }
};
builtins['string-not-greaterp'] = new builtin_function(std_string_not_greaterp, 2, false, [TYPE_STRING, TYPE_STRING], FTYPE_EXPR);
lisp_docs['string-equal'] = 'returns T if S1 is (case insensitive) equal to S2; otherwise, return NIL';
lisp_arg_info['string-equal'] = 'S1 [string], S2 [string]';
std_string_equal = function(a, env) {
  var s1, s2;
  s1 = a[0].value.toLowerCase();
  s2 = a[1].value.toLowerCase();
  if (s1 === s2) {
    return T;
  } else {
    return NIL;
  }
};
builtins['string-equal'] = new builtin_function(std_string_equal, 2, false, [TYPE_STRING, TYPE_STRING], FTYPE_EXPR);
lisp_docs['string-greaterp'] = 'string-greaterp';
lisp_arg_info['string-greaterp'] = 'S1 [string], S2 [string]';
std_string_greaterp = function(a, env) {
  var i, s1, s2, uplim;
  s1 = a[0].value.toLowerCase();
  s2 = a[1].value.toLowerCase();
  if (s1 > s2) {
    uplim = Math.min(s1.length, s2.length);
    for (i = 0; 0 <= uplim ? i < uplim : i > uplim; 0 <= uplim ? i++ : i--) {
      if (s1.charAt(i) !== s2.charAt(i)) {
        return new lisp_integer(i);
      }
    }
    return new lisp_integer(uplim);
  } else {
    return NIL;
  }
};
builtins['string-greaterp'] = new builtin_function(std_string_greaterp, 2, false, [TYPE_STRING, TYPE_STRING], FTYPE_EXPR);
lisp_docs['string-not-lessp'] = 'string-not-lessp';
lisp_arg_info['string-not-lessp'] = 'S1 [string], S2 [string]';
std_string_not_lessp = function(a, env) {
  var i, s1, s2, uplim;
  s1 = a[0].value.toLowerCase();
  s2 = a[1].value.toLowerCase();
  if (s1 >= s2) {
    uplim = Math.min(s1.length, s2.length);
    for (i = 0; 0 <= uplim ? i < uplim : i > uplim; 0 <= uplim ? i++ : i--) {
      if (s1.charAt(i) !== s2.charAt(i)) {
        return new lisp_integer(i);
      }
    }
    return new lisp_integer(uplim);
  } else {
    return NIL;
  }
};
builtins['string-not-lessp'] = new builtin_function(std_string_not_lessp, 2, false, [TYPE_STRING, TYPE_STRING], FTYPE_EXPR);
lisp_docs['string<='] = 'string<=';
lisp_arg_info['string<='] = 'S1 [string], S2 [string]';
std_stringltmarkeqmark = function(a, env) {
  var i, s1, s2, uplim;
  s1 = a[0].value;
  s2 = a[1].value;
  if (s1 <= s2) {
    uplim = Math.min(s1.length, s2.length);
    for (i = 0; 0 <= uplim ? i < uplim : i > uplim; 0 <= uplim ? i++ : i--) {
      if (s1.charAt(i) !== s2.charAt(i)) {
        return new lisp_integer(i);
      }
    }
    return new lisp_integer(uplim);
  } else {
    return NIL;
  }
};
builtins['string<='] = new builtin_function(std_stringltmarkeqmark, 2, false, [TYPE_STRING, TYPE_STRING], FTYPE_EXPR);
lisp_docs['ne'] = 'explaining what ne is / how it is used!';
interpreted_builtins['ne'] = '(de ne (u v)\n(not (eq u v)))';
lisp_docs['eqcar'] = 'explaining what eqcar is / how it is used!';
interpreted_builtins['eqcar'] = '(de eqcar (u v)\n(eq (car u) v))';
lisp_docs['string>'] = 'string>';
lisp_arg_info['string>'] = 'S1 [string], S2 [string]';
std_stringgtmark = function(a, env) {
  var i, s1, s2, uplim;
  s1 = a[0].value;
  s2 = a[1].value;
  if (s1 > s2) {
    uplim = Math.min(s1.length, s2.length);
    for (i = 0; 0 <= uplim ? i < uplim : i > uplim; 0 <= uplim ? i++ : i--) {
      if (s1.charAt(i) !== s2.charAt(i)) {
        return new lisp_integer(i);
      }
    }
    return new lisp_integer(uplim);
  } else {
    return NIL;
  }
};
builtins['string>'] = new builtin_function(std_stringgtmark, 2, false, [TYPE_STRING, TYPE_STRING], FTYPE_EXPR);
lisp_docs['string<'] = 'string<';
lisp_arg_info['string<'] = 'S1 [string], S2 [string]';
std_stringltmark = function(a, env) {
  var i, s1, s2, uplim;
  s1 = a[0].value;
  s2 = a[1].value;
  if (s1 < s2) {
    uplim = Math.min(s1.length, s2.length);
    for (i = 0; 0 <= uplim ? i < uplim : i > uplim; 0 <= uplim ? i++ : i--) {
      if (s1.charAt(i) !== s2.charAt(i)) {
        return new lisp_integer(i);
      }
    }
    return new lisp_integer(uplim);
  } else {
    return NIL;
  }
};
builtins['string<'] = new builtin_function(std_stringltmark, 2, false, [TYPE_STRING, TYPE_STRING], FTYPE_EXPR);
lisp_docs['string='] = 'returns T if S1 is (case sensitive) equal to S2; otherwise, return NIL';
lisp_arg_info['string='] = 'S1 [string], S2 [string]';
std_stringeqmark = function(a, env) {
  var s1, s2;
  s1 = a[0].value;
  s2 = a[1].value;
  if (s1 === s2) {
    return T;
  } else {
    return NIL;
  }
};
builtins['string='] = new builtin_function(std_stringeqmark, 2, false, [TYPE_STRING, TYPE_STRING], FTYPE_EXPR);
lisp_docs['='] = 'synonymous with eqn';
lisp_docs['eqn'] = 'explaining what eqn is / how it is used!';
lisp_arg_info['eqn'] = '[any], [any]';
lisp_arg_info['='] = lisp_arg_info['eqn'];
function std_eqn(a, env) {
  var u = a[0];
  var v = a[1];

  if (u == v) {
    return T;
  }

  if (type_check(u.type, CLASS_NUMBER) && type_check(v.type, CLASS_NUMBER)) {
    if (u.type == TYPE_INTEGER && v.type == TYPE_INTEGER) {
      return (u.value.compare(v.value) == 0) ? T : NIL;
    } else if (u.type == TYPE_FLOATING && v.type == TYPE_FLOATING) {
      return (v.value == u.value) ? T : NIL;
    } else {
      return NIL;
    }
  } else {
    return NIL;
  }
};
builtins['eqn'] = new builtin_function(std_eqn, 2, false, [CLASS_ANY, CLASS_ANY], FTYPE_EXPR);
builtins['='] = builtins['eqn'];
lisp_docs['string-not-equal'] = 'string-not-equal';
lisp_arg_info['string-not-equal'] = 'S1 [string], S2 [string]';
std_string_not_equal = function(a, env) {
  var i, s1, s2, uplim;
  s1 = a[0].value.toLowerCase();
  s2 = a[1].value.toLowerCase();
  if (s1 !== s2) {
    uplim = Math.min(s1.length, s2.length);
    for (i = 0; 0 <= uplim ? i < uplim : i > uplim; 0 <= uplim ? i++ : i--) {
      if (s1.charAt(i) !== s2.charAt(i)) {
        return new lisp_integer(i);
      }
    }
    return new lisp_integer(uplim);
  } else {
    return NIL;
  }
};
builtins['string-not-equal'] = new builtin_function(std_string_not_equal, 2, false, [TYPE_STRING, TYPE_STRING], FTYPE_EXPR);
lisp_docs['<'] = 'synonymous with lessp';
lisp_docs['lessp'] = 'explaining what lessp is / how it is used!';
lisp_arg_info['lessp'] = '[number], [number]';
lisp_arg_info['<'] = lisp_arg_info['lessp'];
function std_lessp(a, env) {
  var args = homogenize_args(a);
  var u = args[0].value;
  var v = args[1].value;

  if (args[0].type == TYPE_INTEGER) {
    return (u.compare(v) == -1) ? T : NIL;
  } else {
    return (u < v) ? T : NIL;
  }
};
builtins['lessp'] = new builtin_function(std_lessp, 2, false, [CLASS_NUMBER, CLASS_NUMBER], FTYPE_EXPR);
builtins['<'] = builtins['lessp'];
lisp_docs['>'] = 'synonymous with greaterp';
lisp_docs['greaterp'] = 'explaining what greaterp is / how it is used!';
lisp_arg_info['greaterp'] = '[number], [number]';
lisp_arg_info['>'] = lisp_arg_info['greaterp'];
function std_greaterp(a, env) {
  var args = homogenize_args(a);
  var u = args[0].value;
  var v = args[1].value;

  if (args[0].type == TYPE_INTEGER) {
    return (u.compare(v) == 1) ? T : NIL;
  } else {
    return (u > v) ? T : NIL;
  }
};
builtins['greaterp'] = new builtin_function(std_greaterp, 2, false, [CLASS_NUMBER, CLASS_NUMBER], FTYPE_EXPR);
builtins['>'] = builtins['greaterp'];
lisp_docs['neq'] = 'explaining what neq is / how it is used!';
interpreted_builtins['neq'] = '(de neq (u v)\n(not (equal u v)))';
lisp_docs['list2vector'] = 'explaining what list2vector is / how it is used!';
lisp_arg_info['list2vector'] = '[pair]';
std_list2vector = function(a, env) {
  var list;
  list = a[0].value;
  return new lisp_vector(list_to_array(list));
};
builtins['list2vector'] = new builtin_function(std_list2vector, 1, false, [TYPE_PAIR], FTYPE_EXPR);
lisp_docs['list2string'] = 'explaining what list2string is / how it is used!';
interpreted_builtins['list2string'] = '(de list2string (l)\n(apply #\'string l))';
lisp_docs['vector2list'] = 'explaining what vector2list is / how it is used!';
lisp_arg_info['vector2list'] = '[vector]';
std_vector2list = function(a, env) {
  var vect;
  vect = a[0].value;
  return array_to_list(vect);
};
builtins['vector2list'] = new builtin_function(std_vector2list, 1, false, [TYPE_VECTOR], FTYPE_EXPR);
lisp_docs['dom-get-element-by-id'] = 'explaining what dom-get-element-by-id is / how it is used!';
interpreted_builtins['dom-get-element-by-id'] = '(de dom-get-element-by-id (id)\n(let ((document (js-eval "document")))\n  (js-method-call document "getElementById" id)))';
lisp_docs['dom-get-value'] = 'explaining what dom-get-value is / how it is used!';
interpreted_builtins['dom-get-value'] = '(de dom-get-value (elm)\n(js-get elm "value"))';
lisp_docs['dom-append'] = 'explaining what dom-append is / how it is used!';
interpreted_builtins['dom-append'] = '(de dom-append (parent &rest children)\n(mapc children\n  (lambda (e)\n    (if (dom? e)\n      (js-method-call parent "appendChild" e)\n      (js-set parent "innerHTML" (string-concat (js-get parent "innerHTML")\n                                                (to-string e)))))))';
lisp_docs['dom-get-title'] = 'explaining what dom-get-title is / how it is used!';
interpreted_builtins['dom-get-title'] = '(de dom-get-title nil\n(js-eval "document.title"))';
lisp_docs['dom-create-button'] = 'explaining what dom-create-button is / how it is used!';
interpreted_builtins['dom-create-button'] = '(de dom-create-button (text &optional props callbacks)\n(dom-create-input (append props (list \'("type" . "button") (cons "value" text))) callbacks))';
lisp_docs['dom-set-event'] = 'explaining what dom-set-event is / how it is used!';
interpreted_builtins['dom-set-event'] = '(de dom-set-event (elm event action)\n(dom-set-attribute elm\n                   event\n                   (string-concat "lisp.evaluate(\'"\n                                  (to-string action)\n                                  "\');")))';
lisp_docs['dom-create'] = 'explaining what dom-create is / how it is used!';
interpreted_builtins['dom-create'] = '(de dom-create (tagname &optional props callbacks)\n(let ((obj (js-method-call (js-eval "document") "createElement" tagname)))\n  (mapc props (lambda (u) (dom-set-attribute obj (car u) (cdr u))))\n  (mapc callbacks (lambda (u) (dom-set-event obj (car u) (cdr u))))\n  obj))';
lisp_docs['dom?'] = 'explaining what dom? is / how it is used!';
interpreted_builtins['dom?'] = '(de dom? (u)\n(when (js-obj? u)\n  (ne (js-get u "appendChild") t)))';
lisp_docs['dom-clear'] = 'explaining what dom-clear is / how it is used!';
interpreted_builtins['dom-clear'] = '(de dom-clear (u)\n(js-set u "innerHTML" ""))';
lisp_docs['dom-remove-attribute'] = 'explaining what dom-remove-attribute is / how it is used!';
interpreted_builtins['dom-remove-attribute'] = '(de dom-remove-attribute (elm attr val)\n(js-method-call elm "removeAttribute" attr val))';
lisp_docs['dom-create-text'] = 'explaining what dom-create-text is / how it is used!';
interpreted_builtins['dom-create-text'] = '(de dom-create-text (&optional props callbacks)\n(dom-create-input (append props \'(("type" . "text"))) callbacks))';
lisp_docs['dom-get-body'] = 'explaining what dom-get-body is / how it is used!';
interpreted_builtins['dom-get-body'] = '(de dom-get-body nil\n(js-eval "document.body"))';
lisp_docs['dom-get-attribute'] = 'explaining what dom-get-attribute is / how it is used!';
interpreted_builtins['dom-get-attribute'] = '(de dom-set-attribute (elm attr val)\n(js-method-call elm "getAttribute" attr val))';
lisp_docs['dom-create-input'] = 'explaining what dom-create-input is / how it is used!';
interpreted_builtins['dom-create-input'] = '(de dom-create-input (&optional props callbacks)\n(dom-create "input" props callbacks))';
lisp_docs['dom-set-title'] = 'explaining what dom-set-title is / how it is used!';
interpreted_builtins['dom-set-title'] = '(de dom-set-title (str)\n(let ((document (js-eval "document")))\n  (js-set document "title" str)))';
lisp_docs['dom-set-attribute'] = 'explaining what dom-set-attribute is / how it is used!';
interpreted_builtins['dom-set-attribute'] = '(de dom-set-attribute (elm attr val)\n(js-method-call elm "setAttribute" attr val))';
lisp_docs['dom-create-checkbox'] = 'explaining what dom-create-checkbox is / how it is used!';
interpreted_builtins['dom-create-checkbox'] = '(de dom-create-checkbox (&optional props callbacks)\n(dom-create-input (cons \'("type" . "checkbox") props) callbacks))';
lisp_docs['char'] = 'explaining what char is / how it is used!';
lisp_arg_info['char'] = '[id]';
std_char = function(a, env) {
  var chr;
  chr = a[0].value;
  return new lisp_integer(chr.charCodeAt(0));
};
builtins['char'] = new builtin_function(std_char, 1, false, [TYPE_ID], FTYPE_FEXPR);
lisp_docs['prog2'] = 'explaining what prog2 is / how it is used!';
lisp_arg_info['prog2'] = '[any], [any]';
function std_prog2(a, env) {
  var u = a[0];
  var v = a[1];

  return v;
};
builtins['prog2'] = new builtin_function(std_prog2, 2, false, [CLASS_ANY, CLASS_ANY], FTYPE_EXPR);
lisp_docs['return'] = 'explaining what return is / how it is used!';
lisp_arg_info['return'] = '[any]';
function std_return(a, env) {
  var u = a[0];

  throw new lisp_error(ERROR_RETURN, u);
};
builtins['return'] = new builtin_function(std_return, 1, false, [CLASS_ANY], FTYPE_EXPR);
lisp_docs['next'] = 'explaining what next is / how it is used!';
interpreted_builtins['next'] = '(dm next (u)\n`(go top))';
lisp_docs['go'] = 'explaining what go is / how it is used!';
lisp_arg_info['go'] = '[id]';
function std_go(a, env) {
  var label = a[0];

  throw new lisp_error(ERROR_GO, label);
};
builtins['go'] = new builtin_function(std_go, 1, false, [TYPE_ID], FTYPE_FEXPR);
lisp_docs['while'] = 'explaining what while is / how it is used!';
interpreted_builtins['while'] = '(dm while (u)\n(let ((test (second u))\n       (body (cddr u)))\n  `(prog nil\ntop   (if ,test nil (return nil))\n      ,@body\n      (go top))))';
lisp_docs['repeat'] = 'explaining what repeat is / how it is used!';
interpreted_builtins['repeat'] = '(dm repeat (u)\n(let ((body (butlast (cdr u)))\n       (test (lastcar u)))\n  `(prog nil\ntop   ,@body\n      (if ,test (return nil) (go top)))))';
lisp_docs['let'] = 'explaining what let is / how it is used!';
interpreted_builtins['let'] = '(dm let (u)\n(prog (arguments body)\n  (setq arguments (second u))\n  (setq body (cddr u))\n  (return `((lambda ,(mapcar arguments (lambda (e) (first e)))\n                  (progn ,@body)) ,@(mapcar arguments (lambda (e) (second e)))))))';
lisp_docs['prog'] = 'explaining what prog is / how it is used!';
lisp_arg_info['prog'] = '[[pair | boolean]]';
function std_prog(a, env) {
  var vars = a[0];
  var program = a[1];

  var retval = NIL;
  var err = UNDEFINED;

  env = env.child_scope();
  for (var p = vars; p != NIL; p = p.cdr) {
    env.variables._set(p.car.value, NIL);
  }

  try {
    for (var i = 0; i < program.length; i++) {
      try {
        program[i].evaluate(env);
      } catch (e) {
        if (e.type == ERROR_GO) {
          for (var j = 0; j < program.length; j++) {
            if (program[j] == e.value) {
              i = j++;
              break;
            }
          }
        } else {
          throw e;
        }
      }
    }
  } catch (e) {
    if (e.type == ERROR_RETURN) {
      retval = e.value;
    } else {
      err = e;
    }
  } finally {
    env.variables = env.variables.outer;
    if (err != UNDEFINED) {
      throw err;
    } else {
      return retval
    }
  }
};
builtins['prog'] = new builtin_function(std_prog, 1, true, [TYPE_PAIR | TYPE_BOOLEAN, CLASS_ANY], FTYPE_FEXPR);
lisp_docs['exit'] = 'explaining what exit is / how it is used!';
interpreted_builtins['exit'] = '(dm exit (u)\n`(return (progn ,@(cdr u))))';
lisp_docs['progn'] = 'explaining what progn is / how it is used!';
lisp_arg_info['progn'] = '[[any]]';
function std_progn(a, env) {
  var u = a[0];

  var ret = NIL;
  for (var i = 0; i < u.length; i++) {
    ret = u[i].evaluate(env);
  }

  return ret;
};
builtins['progn'] = new builtin_function(std_progn, 0, true, [CLASS_ANY], FTYPE_FEXPR);
lisp_docs['errorset'] = 'explaining what errorset is / how it is used!';
lisp_arg_info['errorset'] = '[any], [boolean], [boolean]';
std_errorset = function(a, env) {
  var msgp, tr, u;
  u = a[0];
  msgp = a[1];
  tr = a[2];
  try {
    return u.evaluate(env);
  } catch (e) {
    switch (e.type) {
      case ERROR_INTERNAL:
        if (msgp !== NIL) {
          env.variables.get('ERROUT*').write("***** " + (e.mess.prin2()));
        }
        env.variables.set('EMSG*', e.mess);
        return NIL;
      case ERROR_USER:
        if (msgp !== NIL) {
          env.variables.get('ERROUT*').write("++++ " + (e.value.prin2()) + " " + (e.mess.prin2()));
        }
        env.variables.set('EMSG*', e.mess);
        return e.value;
      case ERROR_GO:
      case ERROR_RETURN:
        throw e;
        break;
      default:
        throw e;
    }
  }
};
builtins['errorset'] = new builtin_function(std_errorset, 3, false, [CLASS_ANY, TYPE_BOOLEAN, TYPE_BOOLEAN], FTYPE_EXPR);
lisp_docs['error'] = 'explaining what error is / how it is used!';
lisp_arg_info['error'] = '[integer], [any]';
function std_error(a, env) {
  var number = a[0];
  var mess = a[1];

  throw new lisp_error(ERROR_USER, number, mess);
};
builtins['error'] = new builtin_function(std_error, 2, false, [TYPE_INTEGER, CLASS_ANY], FTYPE_EXPR);
lisp_docs['explode'] = 'explaining what explode is / how it is used!';
lisp_arg_info['explode'] = '[atom ^ vector]';
function std_explode(a, env) {
  var u = a[0];

  var str = u.prin1();
  var head = new lisp_pair(new lisp_id(str[0], env.oblist), NIL);
  var ptr = head;

  for (var i = 1; i < str.length; i++) {
    ptr.cdr = new lisp_pair(new lisp_id(str[i], env.oblist), NIL);
    ptr = ptr.cdr;
  }

  return head;
};
builtins['explode'] = new builtin_function(std_explode, 1, false, [CLASS_ATOM ^ TYPE_VECTOR], FTYPE_EXPR);
lisp_docs['intern'] = 'explaining what intern is / how it is used!';
lisp_arg_info['intern'] = '[id | string]';
std_intern = function(a, env) {
  var u, _ref;
  u = a[0];
  if (_ref = u.value, __indexOf.call(env.oblist, _ref) < 0) {
    return new lisp_id(u.value, env.oblist);
  } else {
    return env.oblist[u.value];
  }
};
builtins['intern'] = new builtin_function(std_intern, 1, false, [TYPE_ID | TYPE_STRING], FTYPE_EXPR);
lisp_docs['compress'] = 'explaining what compress is / how it is used!';
lisp_arg_info['compress'] = '[pair]';
function std_compress(a, env) {
  var u = a[0];

  var id = [];
  for (var p = u; p != NIL; p = p.cdr) {
    id.push(p.car.prin1());
  }

  return new lisp_id(id.join(''));
};
builtins['compress'] = new builtin_function(std_compress, 1, false, [TYPE_PAIR], FTYPE_EXPR);
lisp_docs['gensym'] = 'explaining what gensym is / how it is used!';
function std_gensym(a, env) {
  var gsnum = env.variables.get('*GSNUM');
  var gensym = new lisp_id('G' + gsnum.prin1());
  env.variables.set('*GSNUM', new lisp_integer(gsnum.value.add(1)));

  return gensym;
};
builtins['gensym'] = new builtin_function(std_gensym, 0, false, [], FTYPE_EXPR);
lisp_docs['remob'] = 'explaining what remob is / how it is used!';
lisp_arg_info['remob'] = '[id]';
function std_remob(a, env) {
  var u = a[0];

  throw new Error('REMOB not implemented (yet)');
};
builtins['remob'] = new builtin_function(std_remob, 1, false, [TYPE_ID], FTYPE_EXPR);
lisp_docs['explode2'] = 'explaining what explode2 is / how it is used!';
lisp_arg_info['explode2'] = '[atom ^ vector]';
std_explode2 = function(a, env) {
  var e, u;
  u = a[0];
  return array_to_list((function() {
    var _i, _len, _ref, _results;
    _ref = u.prin2().split('');
    _results = [];
    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
      e = _ref[_i];
      _results.push(new lisp_id(e, env.oblist));
    }
    return _results;
  })());
};
builtins['explode2'] = new builtin_function(std_explode2, 1, false, [CLASS_ATOM ^ TYPE_VECTOR], FTYPE_EXPR);
lisp_docs['ceiling'] = 'explaining what ceiling is / how it is used!';
lisp_arg_info['ceiling'] = 'X [number]';
std_ceiling = function(a, env) {
  var x;
  x = a[0];
  switch (x.type) {
    case TYPE_INTEGER:
      return x;
    case TYPE_FLOATING:
      return new lisp_integer(Math.ceil(x.value));
  }
};
builtins['ceiling'] = new builtin_function(std_ceiling, 1, false, [CLASS_NUMBER], FTYPE_EXPR);
lisp_docs['divide'] = 'a pair is returned in the form of (quotient . remainder) as if quotient and\nremainder had been called on U and V and consed together';
interpreted_builtins['divide'] = '(de divide (m n)\n(cons (quotient m n) (remainder m n)))';
lisp_docs['sub1'] = 'explaining what sub1 is / how it is used!';
lisp_arg_info['sub1'] = '[number]';
function std_sub1(a, env) {
  var u = a[0];

  if (u.type == TYPE_INTEGER) {
    return new lisp_integer(u.value.prev());
  } else {
    return new lisp_floating(u.value - 1);
  }
};
builtins['sub1'] = new builtin_function(std_sub1, 1, false, [CLASS_NUMBER], FTYPE_EXPR);
lisp_docs['max'] = 'explaining what max is / how it is used!';
lisp_arg_info['max'] = '[[number]]';
function std_max(a, env) {
  var args = homogenize_args(a[0]);

  if (args[0].type == TYPE_INTEGER) {
    var biggest = args[0];
    for (var i = 1; i < args.length; i++) {
      if (args[i].value.compare(biggest.value) == 1) {
        biggest = args[i];
      }
    }
    return biggest;
  } else {
    var biggest = args[0];
    for (var i = 1; i < args.length; i++) {
      if (args[i].value > biggest.value) {
        biggest = args[i];
      }
    }
    return biggest;
  }
};
builtins['max'] = new builtin_function(std_max, 0, true, [CLASS_NUMBER], FTYPE_EXPR);
lisp_docs['times2'] = 'explaining what times2 is / how it is used!';
lisp_arg_info['times2'] = '[number], [number]';
function std_times2(a, env) {
  var args = homogenize_args(a);
  var u = args[0].value;
  var v = args[1].value;

  if (args[0].type == TYPE_INTEGER) {
    return new lisp_integer(u.multiply(v));
  } else {
    return new lisp_floating(u * v);
  }
};
builtins['times2'] = new builtin_function(std_times2, 2, false, [CLASS_NUMBER, CLASS_NUMBER], FTYPE_EXPR);
lisp_docs['float'] = 'explaining what float is / how it is used!';
lisp_arg_info['float'] = '[number]';
function std_float(a, env) {
  var u = a[0];

  if (a[0].type == TYPE_INTEGER) {
    return new lisp_floating(a[0].value.toJSValue());
  } else {
    return u;
  }
};
builtins['float'] = new builtin_function(std_float, 1, false, [CLASS_NUMBER], FTYPE_EXPR);
lisp_docs['*'] = 'synonymous with times';
lisp_docs['times'] = 'explaining what times is / how it is used!';
lisp_arg_info['times'] = '[[number]]';
lisp_arg_info['*'] = lisp_arg_info['times'];
function std_times(a, env) {
  var args = homogenize_args(a[0]);

  if (args[0].type == TYPE_INTEGER) {
    var product = BigInteger(1);
    for (var i = 0; i < args.length; i++) {
      product = product.multiply(args[i].value);
    }
    return new lisp_integer(product);
  } else {
    var product = 1;
    for (var i = 0; i < args.length; i++) {
      product *= args[i].value;
    }
    return new lisp_floating(product);
  }
};
builtins['times'] = new builtin_function(std_times, 0, true, [CLASS_NUMBER], FTYPE_EXPR);
builtins['*'] = builtins['times'];
lisp_docs['min2'] = 'explaining what min2 is / how it is used!';
lisp_arg_info['min2'] = '[number], [number]';
function std_min2(a, env) {
  var args = homogenize_args(a);
  var u = args[0];
  var v = args[1];

  if (args[0].type == TYPE_INTEGER) {
    return (u.value.compare(v.value) == -1) ? u : v;
  } else {
    return (u.value < v.value) ? u : v;;
  }
};
builtins['min2'] = new builtin_function(std_min2, 2, false, [CLASS_NUMBER, CLASS_NUMBER], FTYPE_EXPR);
lisp_docs['-'] = 'synonymous with difference';
lisp_docs['difference'] = 'returns the value of U - V';
lisp_arg_info['difference'] = 'U [number], V [number]';
lisp_arg_info['-'] = lisp_arg_info['difference'];
function std_difference(a, env) {
  var args = homogenize_args(a);
  var u = args[0].value;
  var v = args[1].value;

  if (args[0].type == TYPE_INTEGER) {
    return new lisp_integer(u.subtract(v));
  } else {
    return new lisp_floating(u - v);
  }
};
builtins['difference'] = new builtin_function(std_difference, 2, false, [CLASS_NUMBER, CLASS_NUMBER], FTYPE_EXPR);
builtins['-'] = builtins['difference'];
lisp_docs['//'] = 'synonymous with remainder';
lisp_docs['remainder'] = 'explaining what remainder is / how it is used!';
lisp_arg_info['remainder'] = '[number], [number]';
lisp_arg_info['//'] = lisp_arg_info['remainder'];
function std_remainder(a, env) {
  var args = homogenize_args(a);
  var u = args[0].value;
  var v = args[1].value;

  if (v == 0) {
    throw new Error('***** Attempt to divide by 0 in REMAINDER');
  }

  if (args[0].type == TYPE_INTEGER) {
    return new lisp_integer(u.remainder(v));
  } else {
    return new lisp_floating(u % v);
  }
};
builtins['remainder'] = new builtin_function(std_remainder, 2, false, [CLASS_NUMBER, CLASS_NUMBER], FTYPE_EXPR);
builtins['//'] = builtins['remainder'];
lisp_docs['mod'] = 'explaining what mod is / how it is used!';
interpreted_builtins['mod'] = '(de mod (m n)\n(difference m (times n (floor (quotient m (float n))))))';
lisp_docs['add1'] = 'returns the value of N + 1';
lisp_arg_info['add1'] = 'N [number]';
function std_add1(a, env) {
  var u = a[0];

  if (u.type == TYPE_INTEGER) {
    return new lisp_integer(u.value.next());
  } else {
    return new lisp_floating(u.value + 1);
  }
};
builtins['add1'] = new builtin_function(std_add1, 1, false, [CLASS_NUMBER], FTYPE_EXPR);
lisp_docs['transfersign'] = 'transfer the sign of S to VAL';
interpreted_builtins['transfersign'] = '(de transfersign (s val)\n(if (>= s 0)\n  (abs val)\n  (minus (abs val))))';
lisp_docs['floor'] = 'explaining what floor is / how it is used!';
lisp_arg_info['floor'] = 'X [number]';
std_floor = function(a, env) {
  var x;
  x = a[0];
  switch (x.type) {
    case TYPE_INTEGER:
      return x;
    case TYPE_FLOATING:
      return new lisp_integer(Math.floor(x.value));
  }
};
builtins['floor'] = new builtin_function(std_floor, 1, false, [CLASS_NUMBER], FTYPE_EXPR);
lisp_docs['max2'] = 'explaining what max2 is / how it is used!';
lisp_arg_info['max2'] = '[number], [number]';
function std_max2(a, env) {
  var args = homogenize_args(a);
  var u = args[0];
  var v = args[1];

  if (args[0].type == TYPE_INTEGER) {
    return (u.value.compare(v.value) == 1) ? u : v;
  } else {
    return (u.value > v.value) ? u : v;;
  }
};
builtins['max2'] = new builtin_function(std_max2, 2, false, [CLASS_NUMBER, CLASS_NUMBER], FTYPE_EXPR);
lisp_docs['fix'] = 'returns U as an integer';
lisp_arg_info['fix'] = 'U [number]';
function std_fix(a, env) {
  var u = a[0];

  if (a[0].type == TYPE_FLOATING) {
    return new lisp_integer(BigInteger(a[0].value));
  } else {
    return u;
  }
};
builtins['fix'] = new builtin_function(std_fix, 1, false, [CLASS_NUMBER], FTYPE_EXPR);
lisp_docs['plus2'] = 'explaining what plus2 is / how it is used!';
lisp_arg_info['plus2'] = '[number], [number]';
function std_plus2(a, env) {
  var args = homogenize_args(a);
  var u = args[0].value;
  var v = args[1].value;

  if (args[0].type == TYPE_INTEGER) {
    return new lisp_integer(u.add(v));
  } else {
    return new lisp_floating(u + v);
  }
};
builtins['plus2'] = new builtin_function(std_plus2, 2, false, [CLASS_NUMBER, CLASS_NUMBER], FTYPE_EXPR);
lisp_docs['minus'] = 'explaining what minus is / how it is used!';
lisp_arg_info['minus'] = '[number]';
function std_minus(a, env) {
  var u = a[0];

  if (u.type == TYPE_INTEGER) {
    return new lisp_integer(u.value.negate());
  } else {
    return new lisp_floating(-u.value);
  }
};
builtins['minus'] = new builtin_function(std_minus, 1, false, [CLASS_NUMBER], FTYPE_EXPR);
lisp_docs['expt'] = 'returns U raised to the power of V';
lisp_arg_info['expt'] = 'U [number], V [integer]';
function std_expt(a, env) {
  var args = homogenize_args(a);
  var u = args[0].value;
  var v = args[1].value;

  if (args[0].type == TYPE_INTEGER) {
    return new lisp_integer(u.pow(v));
  } else {
    return new lisp_floating(Math.pow(u, v));
  }
};
builtins['expt'] = new builtin_function(std_expt, 2, false, [CLASS_NUMBER, TYPE_INTEGER], FTYPE_EXPR);
lisp_docs['abs'] = 'returns the absolute value of N';
lisp_arg_info['abs'] = 'N [number]';
function std_abs(a, env) {
  var u = a[0];

  if (u.type == TYPE_INTEGER) {
    return new lisp_integer(u.value.abs());
  } else {
    return new lisp_floating(Math.abs(u.value));
  }
};
builtins['abs'] = new builtin_function(std_abs, 1, false, [CLASS_NUMBER], FTYPE_EXPR);
lisp_docs['+'] = 'synonymous with plus';
lisp_docs['plus'] = 'explaining what plus is / how it is used!';
lisp_arg_info['plus'] = '[[number]]';
lisp_arg_info['+'] = lisp_arg_info['plus'];
function std_plus(a, env) {
  var args = homogenize_args(a[0]);

  if (args[0].type == TYPE_INTEGER) {
    var sum = BigInteger(0);
    for (var i = 0; i < args.length; i++) {
      sum = sum.add(args[i].value);
    }
    return new lisp_integer(sum);
  } else {
    var sum = 0;
    for (var i = 0; i < args.length; i++) {
      sum += args[i].value;
    }
    return new lisp_floating(sum);
  }
};
builtins['plus'] = new builtin_function(std_plus, 0, true, [CLASS_NUMBER], FTYPE_EXPR);
builtins['+'] = builtins['plus'];
lisp_docs['min'] = 'explaining what min is / how it is used!';
lisp_arg_info['min'] = '[[number]]';
function std_min(a, env) {
  var args = homogenize_args(a[0]);

  if (args[0].type == TYPE_INTEGER) {
    var smallest = args[0];
    for (var i = 1; i < args.length; i++) {
      if (args[i].value.compare(smallest.value) == -1) {
        smallest = args[i];
      }
    }
    return smallest;
  } else {
    var smallest = args[0];
    for (var i = 1; i < args.length; i++) {
      if (args[i].value < smallest.value) {
        smallest = args[i];
      }
    }
    return smallest;
  }
};
builtins['min'] = new builtin_function(std_min, 0, true, [CLASS_NUMBER], FTYPE_EXPR);
lisp_docs['round'] = 'explaining what round is / how it is used!';
interpreted_builtins['round'] = '(de round (x)\n(if (fixp x)\n  x\n  (floor (plus x 0.5))))';
lisp_docs['quotient'] = 'explaining what quotient is / how it is used!';
lisp_arg_info['quotient'] = '[number], [number]';
function std_quotient(a, env) {
  var args = homogenize_args(a);
  var u = args[0].value;
  var v = args[1].value;

  if (v == 0) {
    throw new Error('***** Attempt to divide by 0 in QUOTIENT');
  }

  if (args[0].type == TYPE_INTEGER) {
    return new lisp_integer(u.divide(v));
  } else {
    return new lisp_floating(u / v);
  }
};
builtins['quotient'] = new builtin_function(std_quotient, 2, false, [CLASS_NUMBER, CLASS_NUMBER], FTYPE_EXPR);
